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