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 <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    /* 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
119ACPI_STATUS
120AcpiTbAddTable (
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
254PrintHeader:
255    AcpiTbPrintTableHeader (TableDesc->Address, TableDesc->Pointer);
256
257Release:
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
281ACPI_TABLE_HEADER *
282AcpiTbTableOverride (
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 = AcpiOsPhysicalTableOverride (TableHeader,
309        &NewAddress, &NewTableLength);
310    if (ACPI_SUCCESS (Status) && NewAddress && NewTableLength)
311    {
312        /* Map the entire new table */
313
314        NewTable = AcpiOsMapMemory (NewAddress, NewTableLength);
315        if (!NewTable)
316        {
317            ACPI_EXCEPTION ((AE_INFO, AE_NO_MEMORY,
318                "%4.4s %p Attempted physical table override failed",
319                TableHeader->Signature,
320                ACPI_CAST_PTR (void, TableDesc->Address)));
321            return (NULL);
322        }
323
324        OverrideType = "Physical";
325        NewFlags = ACPI_TABLE_ORIGIN_MAPPED;
326        goto FinishOverride;
327    }
328
329    return (NULL); /* There was no override */
330
331
332FinishOverride:
333
334    ACPI_INFO ((AE_INFO,
335        "%4.4s %p %s table override, new table: %p",
336        TableHeader->Signature,
337        ACPI_CAST_PTR (void, TableDesc->Address),
338        OverrideType, NewTable));
339
340    /* We can now unmap/delete the original table (if fully mapped) */
341
342    AcpiTbDeleteTable (TableDesc);
343
344    /* Setup descriptor for the new table */
345
346    TableDesc->Address = NewAddress;
347    TableDesc->Pointer = NewTable;
348    TableDesc->Length = NewTableLength;
349    TableDesc->Flags = NewFlags;
350
351    return (NewTable);
352}
353
354
355/*******************************************************************************
356 *
357 * FUNCTION:    AcpiTbResizeRootTableList
358 *
359 * PARAMETERS:  None
360 *
361 * RETURN:      Status
362 *
363 * DESCRIPTION: Expand the size of global table array
364 *
365 ******************************************************************************/
366
367ACPI_STATUS
368AcpiTbResizeRootTableList (
369    void)
370{
371    ACPI_TABLE_DESC         *Tables;
372    UINT32                  TableCount;
373
374
375    ACPI_FUNCTION_TRACE (TbResizeRootTableList);
376
377
378    /* AllowResize flag is a parameter to AcpiInitializeTables */
379
380    if (!(AcpiGbl_RootTableList.Flags & ACPI_ROOT_ALLOW_RESIZE))
381    {
382        ACPI_ERROR ((AE_INFO, "Resize of Root Table Array is not allowed"));
383        return_ACPI_STATUS (AE_SUPPORT);
384    }
385
386    /* Increase the Table Array size */
387
388    if (AcpiGbl_RootTableList.Flags & ACPI_ROOT_ORIGIN_ALLOCATED)
389    {
390        TableCount = AcpiGbl_RootTableList.MaxTableCount;
391    }
392    else
393    {
394        TableCount = AcpiGbl_RootTableList.CurrentTableCount;
395    }
396
397    Tables = ACPI_ALLOCATE_ZEROED (
398        ((ACPI_SIZE) TableCount + ACPI_ROOT_TABLE_SIZE_INCREMENT) *
399        sizeof (ACPI_TABLE_DESC));
400    if (!Tables)
401    {
402        ACPI_ERROR ((AE_INFO, "Could not allocate new root table array"));
403        return_ACPI_STATUS (AE_NO_MEMORY);
404    }
405
406    /* Copy and free the previous table array */
407
408    if (AcpiGbl_RootTableList.Tables)
409    {
410        ACPI_MEMCPY (Tables, AcpiGbl_RootTableList.Tables,
411            (ACPI_SIZE) TableCount * sizeof (ACPI_TABLE_DESC));
412
413        if (AcpiGbl_RootTableList.Flags & ACPI_ROOT_ORIGIN_ALLOCATED)
414        {
415            ACPI_FREE (AcpiGbl_RootTableList.Tables);
416        }
417    }
418
419    AcpiGbl_RootTableList.Tables = Tables;
420    AcpiGbl_RootTableList.MaxTableCount =
421        TableCount + ACPI_ROOT_TABLE_SIZE_INCREMENT;
422    AcpiGbl_RootTableList.Flags |= ACPI_ROOT_ORIGIN_ALLOCATED;
423
424    return_ACPI_STATUS (AE_OK);
425}
426
427
428/*******************************************************************************
429 *
430 * FUNCTION:    AcpiTbStoreTable
431 *
432 * PARAMETERS:  Address             - Table address
433 *              Table               - Table header
434 *              Length              - Table length
435 *              Flags               - flags
436 *
437 * RETURN:      Status and table index.
438 *
439 * DESCRIPTION: Add an ACPI table to the global table list
440 *
441 ******************************************************************************/
442
443ACPI_STATUS
444AcpiTbStoreTable (
445    ACPI_PHYSICAL_ADDRESS   Address,
446    ACPI_TABLE_HEADER       *Table,
447    UINT32                  Length,
448    UINT8                   Flags,
449    UINT32                  *TableIndex)
450{
451    ACPI_STATUS             Status;
452    ACPI_TABLE_DESC         *NewTable;
453
454
455    /* Ensure that there is room for the table in the Root Table List */
456
457    if (AcpiGbl_RootTableList.CurrentTableCount >=
458        AcpiGbl_RootTableList.MaxTableCount)
459    {
460        Status = AcpiTbResizeRootTableList();
461        if (ACPI_FAILURE (Status))
462        {
463            return (Status);
464        }
465    }
466
467    NewTable = &AcpiGbl_RootTableList.Tables[AcpiGbl_RootTableList.CurrentTableCount];
468
469    /* Initialize added table */
470
471    NewTable->Address = Address;
472    NewTable->Pointer = Table;
473    NewTable->Length = Length;
474    NewTable->OwnerId = 0;
475    NewTable->Flags = Flags;
476
477    ACPI_MOVE_32_TO_32 (&NewTable->Signature, Table->Signature);
478
479    *TableIndex = AcpiGbl_RootTableList.CurrentTableCount;
480    AcpiGbl_RootTableList.CurrentTableCount++;
481    return (AE_OK);
482}
483
484
485/*******************************************************************************
486 *
487 * FUNCTION:    AcpiTbDeleteTable
488 *
489 * PARAMETERS:  TableIndex          - Table index
490 *
491 * RETURN:      None
492 *
493 * DESCRIPTION: Delete one internal ACPI table
494 *
495 ******************************************************************************/
496
497void
498AcpiTbDeleteTable (
499    ACPI_TABLE_DESC         *TableDesc)
500{
501
502    /* Table must be mapped or allocated */
503
504    if (!TableDesc->Pointer)
505    {
506        return;
507    }
508
509    switch (TableDesc->Flags & ACPI_TABLE_ORIGIN_MASK)
510    {
511    case ACPI_TABLE_ORIGIN_MAPPED:
512
513        AcpiOsUnmapMemory (TableDesc->Pointer, TableDesc->Length);
514        break;
515
516    case ACPI_TABLE_ORIGIN_ALLOCATED:
517
518        ACPI_FREE (TableDesc->Pointer);
519        break;
520
521    /* Not mapped or allocated, there is nothing we can do */
522
523    default:
524
525        return;
526    }
527
528    TableDesc->Pointer = NULL;
529}
530
531
532/*******************************************************************************
533 *
534 * FUNCTION:    AcpiTbTerminate
535 *
536 * PARAMETERS:  None
537 *
538 * RETURN:      None
539 *
540 * DESCRIPTION: Delete all internal ACPI tables
541 *
542 ******************************************************************************/
543
544void
545AcpiTbTerminate (
546    void)
547{
548    UINT32                  i;
549
550
551    ACPI_FUNCTION_TRACE (TbTerminate);
552
553
554    (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
555
556    /* Delete the individual tables */
557
558    for (i = 0; i < AcpiGbl_RootTableList.CurrentTableCount; i++)
559    {
560        AcpiTbDeleteTable (&AcpiGbl_RootTableList.Tables[i]);
561    }
562
563    /*
564     * Delete the root table array if allocated locally. Array cannot be
565     * mapped, so we don't need to check for that flag.
566     */
567    if (AcpiGbl_RootTableList.Flags & ACPI_ROOT_ORIGIN_ALLOCATED)
568    {
569        ACPI_FREE (AcpiGbl_RootTableList.Tables);
570    }
571
572    AcpiGbl_RootTableList.Tables = NULL;
573    AcpiGbl_RootTableList.Flags = 0;
574    AcpiGbl_RootTableList.CurrentTableCount = 0;
575
576    ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "ACPI Tables freed\n"));
577    (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
578
579    return_VOID;
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