xref: /haiku/src/add-ons/kernel/bus_managers/acpi/acpica/components/tables/tbinstal.c (revision 776c58b2b56d8bcf33638a2ecb6c697f95a1cbf3)
1 /******************************************************************************
2  *
3  * Module Name: tbinstal - ACPI table installation and removal
4  *
5  *****************************************************************************/
6 
7 /******************************************************************************
8  *
9  * 1. Copyright Notice
10  *
11  * Some or all of this work - Copyright (c) 1999 - 2012, Intel Corp.
12  * All rights reserved.
13  *
14  * 2. License
15  *
16  * 2.1. This is your license from Intel Corp. under its intellectual property
17  * rights. You may have additional license terms from the party that provided
18  * you this software, covering your right to use that party's intellectual
19  * property rights.
20  *
21  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
22  * copy of the source code appearing in this file ("Covered Code") an
23  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
24  * base code distributed originally by Intel ("Original Intel Code") to copy,
25  * make derivatives, distribute, use and display any portion of the Covered
26  * Code in any form, with the right to sublicense such rights; and
27  *
28  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
29  * license (with the right to sublicense), under only those claims of Intel
30  * patents that are infringed by the Original Intel Code, to make, use, sell,
31  * offer to sell, and import the Covered Code and derivative works thereof
32  * solely to the minimum extent necessary to exercise the above copyright
33  * license, and in no event shall the patent license extend to any additions
34  * to or modifications of the Original Intel Code. No other license or right
35  * is granted directly or by implication, estoppel or otherwise;
36  *
37  * The above copyright and patent license is granted only if the following
38  * conditions are met:
39  *
40  * 3. Conditions
41  *
42  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
43  * Redistribution of source code of any substantial portion of the Covered
44  * Code or modification with rights to further distribute source must include
45  * the above Copyright Notice, the above License, this list of Conditions,
46  * and the following Disclaimer and Export Compliance provision. In addition,
47  * Licensee must cause all Covered Code to which Licensee contributes to
48  * contain a file documenting the changes Licensee made to create that Covered
49  * Code and the date of any change. Licensee must include in that file the
50  * documentation of any changes made by any predecessor Licensee. Licensee
51  * must include a prominent statement that the modification is derived,
52  * directly or indirectly, from Original Intel Code.
53  *
54  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
55  * Redistribution of source code of any substantial portion of the Covered
56  * Code or modification without rights to further distribute source must
57  * include the following Disclaimer and Export Compliance provision in the
58  * documentation and/or other materials provided with distribution. In
59  * addition, Licensee may not authorize further sublicense of source of any
60  * portion of the Covered Code, and must include terms to the effect that the
61  * license from Licensee to its licensee is limited to the intellectual
62  * property embodied in the software Licensee provides to its licensee, and
63  * not to intellectual property embodied in modifications its licensee may
64  * make.
65  *
66  * 3.3. Redistribution of Executable. Redistribution in executable form of any
67  * substantial portion of the Covered Code or modification must reproduce the
68  * above Copyright Notice, and the following Disclaimer and Export Compliance
69  * provision in the documentation and/or other materials provided with the
70  * distribution.
71  *
72  * 3.4. Intel retains all right, title, and interest in and to the Original
73  * Intel Code.
74  *
75  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
76  * Intel shall be used in advertising or otherwise to promote the sale, use or
77  * other dealings in products derived from or relating to the Covered Code
78  * without prior written authorization from Intel.
79  *
80  * 4. Disclaimer and Export Compliance
81  *
82  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
83  * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
84  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
85  * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
86  * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
87  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
88  * PARTICULAR PURPOSE.
89  *
90  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
91  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
92  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
93  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
94  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
95  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
96  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
97  * LIMITED REMEDY.
98  *
99  * 4.3. Licensee shall not export, either directly or indirectly, any of this
100  * software or system incorporating such software without first obtaining any
101  * required license or other approval from the U. S. Department of Commerce or
102  * any other agency or department of the United States Government. In the
103  * event Licensee exports any such software from the United States or
104  * re-exports any such software from a foreign destination, Licensee shall
105  * ensure that the distribution and export/re-export of the software is in
106  * compliance with all laws, regulations, orders, or other restrictions of the
107  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
108  * any of its subsidiaries will export/re-export any technical data, process,
109  * software, or service, directly or indirectly, to any country for which the
110  * United States government or any agency thereof requires an export license,
111  * other governmental approval, or letter of assurance, without first obtaining
112  * such license, approval or letter.
113  *
114  *****************************************************************************/
115 
116 
117 #define __TBINSTAL_C__
118 
119 #include "acpi.h"
120 #include "accommon.h"
121 #include "acnamesp.h"
122 #include "actables.h"
123 
124 
125 #define _COMPONENT          ACPI_TABLES
126         ACPI_MODULE_NAME    ("tbinstal")
127 
128 
129 /******************************************************************************
130  *
131  * FUNCTION:    AcpiTbVerifyTable
132  *
133  * PARAMETERS:  TableDesc           - table
134  *
135  * RETURN:      Status
136  *
137  * DESCRIPTION: this function is called to verify and map table
138  *
139  *****************************************************************************/
140 
141 ACPI_STATUS
142 AcpiTbVerifyTable (
143     ACPI_TABLE_DESC         *TableDesc)
144 {
145     ACPI_STATUS             Status = AE_OK;
146 
147 
148     ACPI_FUNCTION_TRACE (TbVerifyTable);
149 
150 
151     /* Map the table if necessary */
152 
153     if (!TableDesc->Pointer)
154     {
155         if ((TableDesc->Flags & ACPI_TABLE_ORIGIN_MASK) ==
156             ACPI_TABLE_ORIGIN_MAPPED)
157         {
158             TableDesc->Pointer = AcpiOsMapMemory (
159                 TableDesc->Address, TableDesc->Length);
160         }
161 
162         if (!TableDesc->Pointer)
163         {
164             return_ACPI_STATUS (AE_NO_MEMORY);
165         }
166     }
167 
168     /* FACS is the odd table, has no standard ACPI header and no checksum */
169 
170     if (!ACPI_COMPARE_NAME (&TableDesc->Signature, ACPI_SIG_FACS))
171     {
172         /* Always calculate checksum, ignore bad checksum if requested */
173 
174         Status = AcpiTbVerifyChecksum (TableDesc->Pointer, TableDesc->Length);
175     }
176 
177     return_ACPI_STATUS (Status);
178 }
179 
180 
181 /*******************************************************************************
182  *
183  * FUNCTION:    AcpiTbAddTable
184  *
185  * PARAMETERS:  TableDesc           - Table descriptor
186  *              TableIndex          - Where the table index is returned
187  *
188  * RETURN:      Status
189  *
190  * DESCRIPTION: This function is called to add an ACPI table. It is used to
191  *              dynamically load tables via the Load and LoadTable AML
192  *              operators.
193  *
194  ******************************************************************************/
195 
196 ACPI_STATUS
197 AcpiTbAddTable (
198     ACPI_TABLE_DESC         *TableDesc,
199     UINT32                  *TableIndex)
200 {
201     UINT32                  i;
202     ACPI_STATUS             Status = AE_OK;
203 
204 
205     ACPI_FUNCTION_TRACE (TbAddTable);
206 
207 
208     if (!TableDesc->Pointer)
209     {
210         Status = AcpiTbVerifyTable (TableDesc);
211         if (ACPI_FAILURE (Status) || !TableDesc->Pointer)
212         {
213             return_ACPI_STATUS (Status);
214         }
215     }
216 
217     /*
218      * Validate the incoming table signature.
219      *
220      * 1) Originally, we checked the table signature for "SSDT" or "PSDT".
221      * 2) We added support for OEMx tables, signature "OEM".
222      * 3) Valid tables were encountered with a null signature, so we just
223      *    gave up on validating the signature, (05/2008).
224      * 4) We encountered non-AML tables such as the MADT, which caused
225      *    interpreter errors and kernel faults. So now, we once again allow
226      *    only "SSDT", "OEMx", and now, also a null signature. (05/2011).
227      */
228     if ((TableDesc->Pointer->Signature[0] != 0x00) &&
229        (!ACPI_COMPARE_NAME (TableDesc->Pointer->Signature, ACPI_SIG_SSDT)) &&
230        (ACPI_STRNCMP (TableDesc->Pointer->Signature, "OEM", 3)))
231     {
232         ACPI_BIOS_ERROR ((AE_INFO,
233             "Table has invalid signature [%4.4s] (0x%8.8X), "
234             "must be SSDT or OEMx",
235             AcpiUtValidAcpiName (*(UINT32 *) TableDesc->Pointer->Signature) ?
236                 TableDesc->Pointer->Signature : "????",
237             *(UINT32 *) TableDesc->Pointer->Signature));
238 
239         return_ACPI_STATUS (AE_BAD_SIGNATURE);
240     }
241 
242     (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
243 
244     /* Check if table is already registered */
245 
246     for (i = 0; i < AcpiGbl_RootTableList.CurrentTableCount; ++i)
247     {
248         if (!AcpiGbl_RootTableList.Tables[i].Pointer)
249         {
250             Status = AcpiTbVerifyTable (&AcpiGbl_RootTableList.Tables[i]);
251             if (ACPI_FAILURE (Status) ||
252                 !AcpiGbl_RootTableList.Tables[i].Pointer)
253             {
254                 continue;
255             }
256         }
257 
258         /*
259          * Check for a table match on the entire table length,
260          * not just the header.
261          */
262         if (TableDesc->Length != AcpiGbl_RootTableList.Tables[i].Length)
263         {
264             continue;
265         }
266 
267         if (ACPI_MEMCMP (TableDesc->Pointer,
268                 AcpiGbl_RootTableList.Tables[i].Pointer,
269                 AcpiGbl_RootTableList.Tables[i].Length))
270         {
271             continue;
272         }
273 
274         /*
275          * Note: the current mechanism does not unregister a table if it is
276          * dynamically unloaded. The related namespace entries are deleted,
277          * but the table remains in the root table list.
278          *
279          * The assumption here is that the number of different tables that
280          * will be loaded is actually small, and there is minimal overhead
281          * in just keeping the table in case it is needed again.
282          *
283          * If this assumption changes in the future (perhaps on large
284          * machines with many table load/unload operations), tables will
285          * need to be unregistered when they are unloaded, and slots in the
286          * root table list should be reused when empty.
287          */
288 
289         /*
290          * Table is already registered.
291          * We can delete the table that was passed as a parameter.
292          */
293         AcpiTbDeleteTable (TableDesc);
294         *TableIndex = i;
295 
296         if (AcpiGbl_RootTableList.Tables[i].Flags & ACPI_TABLE_IS_LOADED)
297         {
298             /* Table is still loaded, this is an error */
299 
300             Status = AE_ALREADY_EXISTS;
301             goto Release;
302         }
303         else
304         {
305             /* Table was unloaded, allow it to be reloaded */
306 
307             TableDesc->Pointer = AcpiGbl_RootTableList.Tables[i].Pointer;
308             TableDesc->Address = AcpiGbl_RootTableList.Tables[i].Address;
309             Status = AE_OK;
310             goto PrintHeader;
311         }
312     }
313 
314     /*
315      * ACPI Table Override:
316      * Allow the host to override dynamically loaded tables.
317      * NOTE: the table is fully mapped at this point, and the mapping will
318      * be deleted by TbTableOverride if the table is actually overridden.
319      */
320     (void) AcpiTbTableOverride (TableDesc->Pointer, TableDesc);
321 
322     /* Add the table to the global root table list */
323 
324     Status = AcpiTbStoreTable (TableDesc->Address, TableDesc->Pointer,
325                 TableDesc->Length, TableDesc->Flags, TableIndex);
326     if (ACPI_FAILURE (Status))
327     {
328         goto Release;
329     }
330 
331 PrintHeader:
332     AcpiTbPrintTableHeader (TableDesc->Address, TableDesc->Pointer);
333 
334 Release:
335     (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
336     return_ACPI_STATUS (Status);
337 }
338 
339 
340 /*******************************************************************************
341  *
342  * FUNCTION:    AcpiTbTableOverride
343  *
344  * PARAMETERS:  TableHeader         - Header for the original table
345  *              TableDesc           - Table descriptor initialized for the
346  *                                    original table. May or may not be mapped.
347  *
348  * RETURN:      Pointer to the entire new table. NULL if table not overridden.
349  *              If overridden, installs the new table within the input table
350  *              descriptor.
351  *
352  * DESCRIPTION: Attempt table override by calling the OSL override functions.
353  *              Note: If the table is overridden, then the entire new table
354  *              is mapped and returned by this function.
355  *
356  ******************************************************************************/
357 
358 ACPI_TABLE_HEADER *
359 AcpiTbTableOverride (
360     ACPI_TABLE_HEADER       *TableHeader,
361     ACPI_TABLE_DESC         *TableDesc)
362 {
363     ACPI_STATUS             Status;
364     ACPI_TABLE_HEADER       *NewTable = NULL;
365     ACPI_PHYSICAL_ADDRESS   NewAddress = 0;
366     UINT32                  NewTableLength = 0;
367     UINT8                   NewFlags;
368     char                    *OverrideType;
369 
370 
371     /* (1) Attempt logical override (returns a logical address) */
372 
373     Status = AcpiOsTableOverride (TableHeader, &NewTable);
374     if (ACPI_SUCCESS (Status) && NewTable)
375     {
376         NewAddress = ACPI_PTR_TO_PHYSADDR (NewTable);
377         NewTableLength = NewTable->Length;
378         NewFlags = ACPI_TABLE_ORIGIN_OVERRIDE;
379         OverrideType = "Logical";
380         goto FinishOverride;
381     }
382 
383     /* (2) Attempt physical override (returns a physical address) */
384 
385     Status = AcpiOsPhysicalTableOverride (TableHeader,
386         &NewAddress, &NewTableLength);
387     if (ACPI_SUCCESS (Status) && NewAddress && NewTableLength)
388     {
389         /* Map the entire new table */
390 
391         NewTable = AcpiOsMapMemory (NewAddress, NewTableLength);
392         if (!NewTable)
393         {
394             ACPI_EXCEPTION ((AE_INFO, AE_NO_MEMORY,
395                 "%4.4s %p Attempted physical table override failed",
396                 TableHeader->Signature,
397                 ACPI_CAST_PTR (void, TableDesc->Address)));
398             return (NULL);
399         }
400 
401         OverrideType = "Physical";
402         NewFlags = ACPI_TABLE_ORIGIN_MAPPED;
403         goto FinishOverride;
404     }
405 
406     return (NULL); /* There was no override */
407 
408 
409 FinishOverride:
410 
411     ACPI_INFO ((AE_INFO,
412         "%4.4s %p %s table override, new table: %p",
413         TableHeader->Signature,
414         ACPI_CAST_PTR (void, TableDesc->Address),
415         OverrideType, NewTable));
416 
417     /* We can now unmap/delete the original table (if fully mapped) */
418 
419     AcpiTbDeleteTable (TableDesc);
420 
421     /* Setup descriptor for the new table */
422 
423     TableDesc->Address = NewAddress;
424     TableDesc->Pointer = NewTable;
425     TableDesc->Length = NewTableLength;
426     TableDesc->Flags = NewFlags;
427 
428     return (NewTable);
429 }
430 
431 
432 /*******************************************************************************
433  *
434  * FUNCTION:    AcpiTbResizeRootTableList
435  *
436  * PARAMETERS:  None
437  *
438  * RETURN:      Status
439  *
440  * DESCRIPTION: Expand the size of global table array
441  *
442  ******************************************************************************/
443 
444 ACPI_STATUS
445 AcpiTbResizeRootTableList (
446     void)
447 {
448     ACPI_TABLE_DESC         *Tables;
449     UINT32                  TableCount;
450 
451 
452     ACPI_FUNCTION_TRACE (TbResizeRootTableList);
453 
454 
455     /* AllowResize flag is a parameter to AcpiInitializeTables */
456 
457     if (!(AcpiGbl_RootTableList.Flags & ACPI_ROOT_ALLOW_RESIZE))
458     {
459         ACPI_ERROR ((AE_INFO, "Resize of Root Table Array is not allowed"));
460         return_ACPI_STATUS (AE_SUPPORT);
461     }
462 
463     /* Increase the Table Array size */
464 
465     if (AcpiGbl_RootTableList.Flags & ACPI_ROOT_ORIGIN_ALLOCATED)
466     {
467         TableCount = AcpiGbl_RootTableList.MaxTableCount;
468     }
469     else
470     {
471         TableCount = AcpiGbl_RootTableList.CurrentTableCount;
472     }
473 
474     Tables = ACPI_ALLOCATE_ZEROED (
475         ((ACPI_SIZE) TableCount + ACPI_ROOT_TABLE_SIZE_INCREMENT) *
476         sizeof (ACPI_TABLE_DESC));
477     if (!Tables)
478     {
479         ACPI_ERROR ((AE_INFO, "Could not allocate new root table array"));
480         return_ACPI_STATUS (AE_NO_MEMORY);
481     }
482 
483     /* Copy and free the previous table array */
484 
485     if (AcpiGbl_RootTableList.Tables)
486     {
487         ACPI_MEMCPY (Tables, AcpiGbl_RootTableList.Tables,
488             (ACPI_SIZE) TableCount * sizeof (ACPI_TABLE_DESC));
489 
490         if (AcpiGbl_RootTableList.Flags & ACPI_ROOT_ORIGIN_ALLOCATED)
491         {
492             ACPI_FREE (AcpiGbl_RootTableList.Tables);
493         }
494     }
495 
496     AcpiGbl_RootTableList.Tables = Tables;
497     AcpiGbl_RootTableList.MaxTableCount =
498         TableCount + ACPI_ROOT_TABLE_SIZE_INCREMENT;
499     AcpiGbl_RootTableList.Flags |= ACPI_ROOT_ORIGIN_ALLOCATED;
500 
501     return_ACPI_STATUS (AE_OK);
502 }
503 
504 
505 /*******************************************************************************
506  *
507  * FUNCTION:    AcpiTbStoreTable
508  *
509  * PARAMETERS:  Address             - Table address
510  *              Table               - Table header
511  *              Length              - Table length
512  *              Flags               - flags
513  *
514  * RETURN:      Status and table index.
515  *
516  * DESCRIPTION: Add an ACPI table to the global table list
517  *
518  ******************************************************************************/
519 
520 ACPI_STATUS
521 AcpiTbStoreTable (
522     ACPI_PHYSICAL_ADDRESS   Address,
523     ACPI_TABLE_HEADER       *Table,
524     UINT32                  Length,
525     UINT8                   Flags,
526     UINT32                  *TableIndex)
527 {
528     ACPI_STATUS             Status;
529     ACPI_TABLE_DESC         *NewTable;
530 
531 
532     /* Ensure that there is room for the table in the Root Table List */
533 
534     if (AcpiGbl_RootTableList.CurrentTableCount >=
535         AcpiGbl_RootTableList.MaxTableCount)
536     {
537         Status = AcpiTbResizeRootTableList();
538         if (ACPI_FAILURE (Status))
539         {
540             return (Status);
541         }
542     }
543 
544     NewTable = &AcpiGbl_RootTableList.Tables[AcpiGbl_RootTableList.CurrentTableCount];
545 
546     /* Initialize added table */
547 
548     NewTable->Address = Address;
549     NewTable->Pointer = Table;
550     NewTable->Length = Length;
551     NewTable->OwnerId = 0;
552     NewTable->Flags = Flags;
553 
554     ACPI_MOVE_32_TO_32 (&NewTable->Signature, Table->Signature);
555 
556     *TableIndex = AcpiGbl_RootTableList.CurrentTableCount;
557     AcpiGbl_RootTableList.CurrentTableCount++;
558     return (AE_OK);
559 }
560 
561 
562 /*******************************************************************************
563  *
564  * FUNCTION:    AcpiTbDeleteTable
565  *
566  * PARAMETERS:  TableIndex          - Table index
567  *
568  * RETURN:      None
569  *
570  * DESCRIPTION: Delete one internal ACPI table
571  *
572  ******************************************************************************/
573 
574 void
575 AcpiTbDeleteTable (
576     ACPI_TABLE_DESC         *TableDesc)
577 {
578 
579     /* Table must be mapped or allocated */
580 
581     if (!TableDesc->Pointer)
582     {
583         return;
584     }
585 
586     switch (TableDesc->Flags & ACPI_TABLE_ORIGIN_MASK)
587     {
588     case ACPI_TABLE_ORIGIN_MAPPED:
589         AcpiOsUnmapMemory (TableDesc->Pointer, TableDesc->Length);
590         break;
591 
592     case ACPI_TABLE_ORIGIN_ALLOCATED:
593         ACPI_FREE (TableDesc->Pointer);
594         break;
595 
596     /* Not mapped or allocated, there is nothing we can do */
597 
598     default:
599         return;
600     }
601 
602     TableDesc->Pointer = NULL;
603 }
604 
605 
606 /*******************************************************************************
607  *
608  * FUNCTION:    AcpiTbTerminate
609  *
610  * PARAMETERS:  None
611  *
612  * RETURN:      None
613  *
614  * DESCRIPTION: Delete all internal ACPI tables
615  *
616  ******************************************************************************/
617 
618 void
619 AcpiTbTerminate (
620     void)
621 {
622     UINT32                  i;
623 
624 
625     ACPI_FUNCTION_TRACE (TbTerminate);
626 
627 
628     (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
629 
630     /* Delete the individual tables */
631 
632     for (i = 0; i < AcpiGbl_RootTableList.CurrentTableCount; i++)
633     {
634         AcpiTbDeleteTable (&AcpiGbl_RootTableList.Tables[i]);
635     }
636 
637     /*
638      * Delete the root table array if allocated locally. Array cannot be
639      * mapped, so we don't need to check for that flag.
640      */
641     if (AcpiGbl_RootTableList.Flags & ACPI_ROOT_ORIGIN_ALLOCATED)
642     {
643         ACPI_FREE (AcpiGbl_RootTableList.Tables);
644     }
645 
646     AcpiGbl_RootTableList.Tables = NULL;
647     AcpiGbl_RootTableList.Flags = 0;
648     AcpiGbl_RootTableList.CurrentTableCount = 0;
649 
650     ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "ACPI Tables freed\n"));
651     (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
652 
653     return_VOID;
654 }
655 
656 
657 /*******************************************************************************
658  *
659  * FUNCTION:    AcpiTbDeleteNamespaceByOwner
660  *
661  * PARAMETERS:  TableIndex          - Table index
662  *
663  * RETURN:      Status
664  *
665  * DESCRIPTION: Delete all namespace objects created when this table was loaded.
666  *
667  ******************************************************************************/
668 
669 ACPI_STATUS
670 AcpiTbDeleteNamespaceByOwner (
671     UINT32                  TableIndex)
672 {
673     ACPI_OWNER_ID           OwnerId;
674     ACPI_STATUS             Status;
675 
676 
677     ACPI_FUNCTION_TRACE (TbDeleteNamespaceByOwner);
678 
679 
680     Status = AcpiUtAcquireMutex (ACPI_MTX_TABLES);
681     if (ACPI_FAILURE (Status))
682     {
683         return_ACPI_STATUS (Status);
684     }
685 
686     if (TableIndex >= AcpiGbl_RootTableList.CurrentTableCount)
687     {
688         /* The table index does not exist */
689 
690         (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
691         return_ACPI_STATUS (AE_NOT_EXIST);
692     }
693 
694     /* Get the owner ID for this table, used to delete namespace nodes */
695 
696     OwnerId = AcpiGbl_RootTableList.Tables[TableIndex].OwnerId;
697     (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
698 
699     /*
700      * Need to acquire the namespace writer lock to prevent interference
701      * with any concurrent namespace walks. The interpreter must be
702      * released during the deletion since the acquisition of the deletion
703      * lock may block, and also since the execution of a namespace walk
704      * must be allowed to use the interpreter.
705      */
706     (void) AcpiUtReleaseMutex (ACPI_MTX_INTERPRETER);
707     Status = AcpiUtAcquireWriteLock (&AcpiGbl_NamespaceRwLock);
708 
709     AcpiNsDeleteNamespaceByOwner (OwnerId);
710     if (ACPI_FAILURE (Status))
711     {
712         return_ACPI_STATUS (Status);
713     }
714 
715     AcpiUtReleaseWriteLock (&AcpiGbl_NamespaceRwLock);
716 
717     Status = AcpiUtAcquireMutex (ACPI_MTX_INTERPRETER);
718     return_ACPI_STATUS (Status);
719 }
720 
721 
722 /*******************************************************************************
723  *
724  * FUNCTION:    AcpiTbAllocateOwnerId
725  *
726  * PARAMETERS:  TableIndex          - Table index
727  *
728  * RETURN:      Status
729  *
730  * DESCRIPTION: Allocates OwnerId in TableDesc
731  *
732  ******************************************************************************/
733 
734 ACPI_STATUS
735 AcpiTbAllocateOwnerId (
736     UINT32                  TableIndex)
737 {
738     ACPI_STATUS             Status = AE_BAD_PARAMETER;
739 
740 
741     ACPI_FUNCTION_TRACE (TbAllocateOwnerId);
742 
743 
744     (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
745     if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount)
746     {
747         Status = AcpiUtAllocateOwnerId
748                     (&(AcpiGbl_RootTableList.Tables[TableIndex].OwnerId));
749     }
750 
751     (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
752     return_ACPI_STATUS (Status);
753 }
754 
755 
756 /*******************************************************************************
757  *
758  * FUNCTION:    AcpiTbReleaseOwnerId
759  *
760  * PARAMETERS:  TableIndex          - Table index
761  *
762  * RETURN:      Status
763  *
764  * DESCRIPTION: Releases OwnerId in TableDesc
765  *
766  ******************************************************************************/
767 
768 ACPI_STATUS
769 AcpiTbReleaseOwnerId (
770     UINT32                  TableIndex)
771 {
772     ACPI_STATUS             Status = AE_BAD_PARAMETER;
773 
774 
775     ACPI_FUNCTION_TRACE (TbReleaseOwnerId);
776 
777 
778     (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
779     if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount)
780     {
781         AcpiUtReleaseOwnerId (
782             &(AcpiGbl_RootTableList.Tables[TableIndex].OwnerId));
783         Status = AE_OK;
784     }
785 
786     (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
787     return_ACPI_STATUS (Status);
788 }
789 
790 
791 /*******************************************************************************
792  *
793  * FUNCTION:    AcpiTbGetOwnerId
794  *
795  * PARAMETERS:  TableIndex          - Table index
796  *              OwnerId             - Where the table OwnerId is returned
797  *
798  * RETURN:      Status
799  *
800  * DESCRIPTION: returns OwnerId for the ACPI table
801  *
802  ******************************************************************************/
803 
804 ACPI_STATUS
805 AcpiTbGetOwnerId (
806     UINT32                  TableIndex,
807     ACPI_OWNER_ID           *OwnerId)
808 {
809     ACPI_STATUS             Status = AE_BAD_PARAMETER;
810 
811 
812     ACPI_FUNCTION_TRACE (TbGetOwnerId);
813 
814 
815     (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
816     if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount)
817     {
818         *OwnerId = AcpiGbl_RootTableList.Tables[TableIndex].OwnerId;
819         Status = AE_OK;
820     }
821 
822     (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
823     return_ACPI_STATUS (Status);
824 }
825 
826 
827 /*******************************************************************************
828  *
829  * FUNCTION:    AcpiTbIsTableLoaded
830  *
831  * PARAMETERS:  TableIndex          - Table index
832  *
833  * RETURN:      Table Loaded Flag
834  *
835  ******************************************************************************/
836 
837 BOOLEAN
838 AcpiTbIsTableLoaded (
839     UINT32                  TableIndex)
840 {
841     BOOLEAN                 IsLoaded = FALSE;
842 
843 
844     (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
845     if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount)
846     {
847         IsLoaded = (BOOLEAN)
848             (AcpiGbl_RootTableList.Tables[TableIndex].Flags &
849             ACPI_TABLE_IS_LOADED);
850     }
851 
852     (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
853     return (IsLoaded);
854 }
855 
856 
857 /*******************************************************************************
858  *
859  * FUNCTION:    AcpiTbSetTableLoadedFlag
860  *
861  * PARAMETERS:  TableIndex          - Table index
862  *              IsLoaded            - TRUE if table is loaded, FALSE otherwise
863  *
864  * RETURN:      None
865  *
866  * DESCRIPTION: Sets the table loaded flag to either TRUE or FALSE.
867  *
868  ******************************************************************************/
869 
870 void
871 AcpiTbSetTableLoadedFlag (
872     UINT32                  TableIndex,
873     BOOLEAN                 IsLoaded)
874 {
875 
876     (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
877     if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount)
878     {
879         if (IsLoaded)
880         {
881             AcpiGbl_RootTableList.Tables[TableIndex].Flags |=
882                 ACPI_TABLE_IS_LOADED;
883         }
884         else
885         {
886             AcpiGbl_RootTableList.Tables[TableIndex].Flags &=
887                 ~ACPI_TABLE_IS_LOADED;
888         }
889     }
890 
891     (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
892 }
893