tbdata.c revision 1.7
1/******************************************************************************
2 *
3 * Module Name: tbdata - Table manager data structure functions
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2016, 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#include "acpi.h"
45#include "accommon.h"
46#include "acnamesp.h"
47#include "actables.h"
48#include "acevents.h"
49
50#define _COMPONENT          ACPI_TABLES
51        ACPI_MODULE_NAME    ("tbdata")
52
53
54/*******************************************************************************
55 *
56 * FUNCTION:    AcpiTbInitTableDescriptor
57 *
58 * PARAMETERS:  TableDesc               - Table descriptor
59 *              Address                 - Physical address of the table
60 *              Flags                   - Allocation flags of the table
61 *              Table                   - Pointer to the table
62 *
63 * RETURN:      None
64 *
65 * DESCRIPTION: Initialize a new table descriptor
66 *
67 ******************************************************************************/
68
69void
70AcpiTbInitTableDescriptor (
71    ACPI_TABLE_DESC         *TableDesc,
72    ACPI_PHYSICAL_ADDRESS   Address,
73    UINT8                   Flags,
74    ACPI_TABLE_HEADER       *Table)
75{
76
77    /*
78     * Initialize the table descriptor. Set the pointer to NULL, since the
79     * table is not fully mapped at this time.
80     */
81    memset (TableDesc, 0, sizeof (ACPI_TABLE_DESC));
82    TableDesc->Address = Address;
83    TableDesc->Length = Table->Length;
84    TableDesc->Flags = Flags;
85    ACPI_MOVE_32_TO_32 (TableDesc->Signature.Ascii, Table->Signature);
86}
87
88
89/*******************************************************************************
90 *
91 * FUNCTION:    AcpiTbAcquireTable
92 *
93 * PARAMETERS:  TableDesc           - Table descriptor
94 *              TablePtr            - Where table is returned
95 *              TableLength         - Where table length is returned
96 *              TableFlags          - Where table allocation flags are returned
97 *
98 * RETURN:      Status
99 *
100 * DESCRIPTION: Acquire an ACPI table. It can be used for tables not
101 *              maintained in the AcpiGbl_RootTableList.
102 *
103 ******************************************************************************/
104
105ACPI_STATUS
106AcpiTbAcquireTable (
107    ACPI_TABLE_DESC         *TableDesc,
108    ACPI_TABLE_HEADER       **TablePtr,
109    UINT32                  *TableLength,
110    UINT8                   *TableFlags)
111{
112    ACPI_TABLE_HEADER       *Table = NULL;
113
114
115    switch (TableDesc->Flags & ACPI_TABLE_ORIGIN_MASK)
116    {
117    case ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL:
118
119        Table = AcpiOsMapMemory (TableDesc->Address, TableDesc->Length);
120        break;
121
122    case ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL:
123    case ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL:
124
125        Table = ACPI_CAST_PTR (ACPI_TABLE_HEADER,
126            ACPI_PHYSADDR_TO_PTR (TableDesc->Address));
127        break;
128
129    default:
130
131        break;
132    }
133
134    /* Table is not valid yet */
135
136    if (!Table)
137    {
138        return (AE_NO_MEMORY);
139    }
140
141    /* Fill the return values */
142
143    *TablePtr = Table;
144    *TableLength = TableDesc->Length;
145    *TableFlags = TableDesc->Flags;
146    return (AE_OK);
147}
148
149
150/*******************************************************************************
151 *
152 * FUNCTION:    AcpiTbReleaseTable
153 *
154 * PARAMETERS:  Table               - Pointer for the table
155 *              TableLength         - Length for the table
156 *              TableFlags          - Allocation flags for the table
157 *
158 * RETURN:      None
159 *
160 * DESCRIPTION: Release a table. The inverse of AcpiTbAcquireTable().
161 *
162 ******************************************************************************/
163
164void
165AcpiTbReleaseTable (
166    ACPI_TABLE_HEADER       *Table,
167    UINT32                  TableLength,
168    UINT8                   TableFlags)
169{
170
171    switch (TableFlags & ACPI_TABLE_ORIGIN_MASK)
172    {
173    case ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL:
174
175        AcpiOsUnmapMemory (Table, TableLength);
176        break;
177
178    case ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL:
179    case ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL:
180    default:
181
182        break;
183    }
184}
185
186
187/*******************************************************************************
188 *
189 * FUNCTION:    AcpiTbAcquireTempTable
190 *
191 * PARAMETERS:  TableDesc           - Table descriptor to be acquired
192 *              Address             - Address of the table
193 *              Flags               - Allocation flags of the table
194 *
195 * RETURN:      Status
196 *
197 * DESCRIPTION: This function validates the table header to obtain the length
198 *              of a table and fills the table descriptor to make its state as
199 *              "INSTALLED". Such a table descriptor is only used for verified
200 *              installation.
201 *
202 ******************************************************************************/
203
204ACPI_STATUS
205AcpiTbAcquireTempTable (
206    ACPI_TABLE_DESC         *TableDesc,
207    ACPI_PHYSICAL_ADDRESS   Address,
208    UINT8                   Flags)
209{
210    ACPI_TABLE_HEADER       *TableHeader;
211
212
213    switch (Flags & ACPI_TABLE_ORIGIN_MASK)
214    {
215    case ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL:
216
217        /* Get the length of the full table from the header */
218
219        TableHeader = AcpiOsMapMemory (Address, sizeof (ACPI_TABLE_HEADER));
220        if (!TableHeader)
221        {
222            return (AE_NO_MEMORY);
223        }
224
225        AcpiTbInitTableDescriptor (TableDesc, Address, Flags, TableHeader);
226        AcpiOsUnmapMemory (TableHeader, sizeof (ACPI_TABLE_HEADER));
227        return (AE_OK);
228
229    case ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL:
230    case ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL:
231
232        TableHeader = ACPI_CAST_PTR (ACPI_TABLE_HEADER,
233            ACPI_PHYSADDR_TO_PTR (Address));
234        if (!TableHeader)
235        {
236            return (AE_NO_MEMORY);
237        }
238
239        AcpiTbInitTableDescriptor (TableDesc, Address, Flags, TableHeader);
240        return (AE_OK);
241
242    default:
243
244        break;
245    }
246
247    /* Table is not valid yet */
248
249    return (AE_NO_MEMORY);
250}
251
252
253/*******************************************************************************
254 *
255 * FUNCTION:    AcpiTbReleaseTempTable
256 *
257 * PARAMETERS:  TableDesc           - Table descriptor to be released
258 *
259 * RETURN:      Status
260 *
261 * DESCRIPTION: The inverse of AcpiTbAcquireTempTable().
262 *
263 *****************************************************************************/
264
265void
266AcpiTbReleaseTempTable (
267    ACPI_TABLE_DESC         *TableDesc)
268{
269
270    /*
271     * Note that the .Address is maintained by the callers of
272     * AcpiTbAcquireTempTable(), thus do not invoke AcpiTbUninstallTable()
273     * where .Address will be freed.
274     */
275    AcpiTbInvalidateTable (TableDesc);
276}
277
278
279/******************************************************************************
280 *
281 * FUNCTION:    AcpiTbValidateTable
282 *
283 * PARAMETERS:  TableDesc           - Table descriptor
284 *
285 * RETURN:      Status
286 *
287 * DESCRIPTION: This function is called to validate the table, the returned
288 *              table descriptor is in "VALIDATED" state.
289 *
290 *****************************************************************************/
291
292ACPI_STATUS
293AcpiTbValidateTable (
294    ACPI_TABLE_DESC         *TableDesc)
295{
296    ACPI_STATUS             Status = AE_OK;
297
298
299    ACPI_FUNCTION_TRACE (TbValidateTable);
300
301
302    /* Validate the table if necessary */
303
304    if (!TableDesc->Pointer)
305    {
306        Status = AcpiTbAcquireTable (TableDesc, &TableDesc->Pointer,
307            &TableDesc->Length, &TableDesc->Flags);
308        if (!TableDesc->Pointer)
309        {
310            Status = AE_NO_MEMORY;
311        }
312    }
313
314    return_ACPI_STATUS (Status);
315}
316
317
318/*******************************************************************************
319 *
320 * FUNCTION:    AcpiTbInvalidateTable
321 *
322 * PARAMETERS:  TableDesc           - Table descriptor
323 *
324 * RETURN:      None
325 *
326 * DESCRIPTION: Invalidate one internal ACPI table, this is the inverse of
327 *              AcpiTbValidateTable().
328 *
329 ******************************************************************************/
330
331void
332AcpiTbInvalidateTable (
333    ACPI_TABLE_DESC         *TableDesc)
334{
335
336    ACPI_FUNCTION_TRACE (TbInvalidateTable);
337
338
339    /* Table must be validated */
340
341    if (!TableDesc->Pointer)
342    {
343        return_VOID;
344    }
345
346    AcpiTbReleaseTable (TableDesc->Pointer, TableDesc->Length,
347        TableDesc->Flags);
348    TableDesc->Pointer = NULL;
349
350    return_VOID;
351}
352
353
354/******************************************************************************
355 *
356 * FUNCTION:    AcpiTbValidateTempTable
357 *
358 * PARAMETERS:  TableDesc           - Table descriptor
359 *
360 * RETURN:      Status
361 *
362 * DESCRIPTION: This function is called to validate the table, the returned
363 *              table descriptor is in "VALIDATED" state.
364 *
365 *****************************************************************************/
366
367ACPI_STATUS
368AcpiTbValidateTempTable (
369    ACPI_TABLE_DESC         *TableDesc)
370{
371
372    if (!TableDesc->Pointer && !AcpiGbl_VerifyTableChecksum)
373    {
374        /*
375         * Only validates the header of the table.
376         * Note that Length contains the size of the mapping after invoking
377         * this work around, this value is required by
378         * AcpiTbReleaseTempTable().
379         * We can do this because in AcpiInitTableDescriptor(), the Length
380         * field of the installed descriptor is filled with the actual
381         * table length obtaining from the table header.
382         */
383        TableDesc->Length = sizeof (ACPI_TABLE_HEADER);
384    }
385
386    return (AcpiTbValidateTable (TableDesc));
387}
388
389
390/******************************************************************************
391 *
392 * FUNCTION:    AcpiTbVerifyTempTable
393 *
394 * PARAMETERS:  TableDesc           - Table descriptor
395 *              Signature           - Table signature to verify
396 *
397 * RETURN:      Status
398 *
399 * DESCRIPTION: This function is called to validate and verify the table, the
400 *              returned table descriptor is in "VALIDATED" state.
401 *
402 *****************************************************************************/
403
404ACPI_STATUS
405AcpiTbVerifyTempTable (
406    ACPI_TABLE_DESC         *TableDesc,
407    const char              *Signature)
408{
409    ACPI_STATUS             Status = AE_OK;
410
411
412    ACPI_FUNCTION_TRACE (TbVerifyTempTable);
413
414
415    /* Validate the table */
416
417    Status = AcpiTbValidateTempTable (TableDesc);
418    if (ACPI_FAILURE (Status))
419    {
420        return_ACPI_STATUS (AE_NO_MEMORY);
421    }
422
423    /* If a particular signature is expected (DSDT/FACS), it must match */
424
425    if (Signature &&
426        !ACPI_COMPARE_NAME (&TableDesc->Signature, Signature))
427    {
428        ACPI_BIOS_ERROR ((AE_INFO,
429            "Invalid signature 0x%X for ACPI table, expected [%s]",
430            TableDesc->Signature.Integer, Signature));
431        Status = AE_BAD_SIGNATURE;
432        goto InvalidateAndExit;
433    }
434
435    /* Verify the checksum */
436
437    if (AcpiGbl_VerifyTableChecksum)
438    {
439        Status = AcpiTbVerifyChecksum (TableDesc->Pointer, TableDesc->Length);
440        if (ACPI_FAILURE (Status))
441        {
442            ACPI_EXCEPTION ((AE_INFO, AE_NO_MEMORY,
443                "%4.4s 0x%8.8X%8.8X"
444                " Attempted table install failed",
445                AcpiUtValidNameseg (TableDesc->Signature.Ascii) ?
446                    TableDesc->Signature.Ascii : "????",
447                ACPI_FORMAT_UINT64 (TableDesc->Address)));
448
449            goto InvalidateAndExit;
450        }
451    }
452
453    return_ACPI_STATUS (AE_OK);
454
455InvalidateAndExit:
456    AcpiTbInvalidateTable (TableDesc);
457    return_ACPI_STATUS (Status);
458}
459
460
461/*******************************************************************************
462 *
463 * FUNCTION:    AcpiTbResizeRootTableList
464 *
465 * PARAMETERS:  None
466 *
467 * RETURN:      Status
468 *
469 * DESCRIPTION: Expand the size of global table array
470 *
471 ******************************************************************************/
472
473ACPI_STATUS
474AcpiTbResizeRootTableList (
475    void)
476{
477    ACPI_TABLE_DESC         *Tables;
478    UINT32                  TableCount;
479
480
481    ACPI_FUNCTION_TRACE (TbResizeRootTableList);
482
483
484    /* AllowResize flag is a parameter to AcpiInitializeTables */
485
486    if (!(AcpiGbl_RootTableList.Flags & ACPI_ROOT_ALLOW_RESIZE))
487    {
488        ACPI_ERROR ((AE_INFO, "Resize of Root Table Array is not allowed"));
489        return_ACPI_STATUS (AE_SUPPORT);
490    }
491
492    /* Increase the Table Array size */
493
494    if (AcpiGbl_RootTableList.Flags & ACPI_ROOT_ORIGIN_ALLOCATED)
495    {
496        TableCount = AcpiGbl_RootTableList.MaxTableCount;
497    }
498    else
499    {
500        TableCount = AcpiGbl_RootTableList.CurrentTableCount;
501    }
502
503    Tables = ACPI_ALLOCATE_ZEROED (
504        ((ACPI_SIZE) TableCount + ACPI_ROOT_TABLE_SIZE_INCREMENT) *
505        sizeof (ACPI_TABLE_DESC));
506    if (!Tables)
507    {
508        ACPI_ERROR ((AE_INFO, "Could not allocate new root table array"));
509        return_ACPI_STATUS (AE_NO_MEMORY);
510    }
511
512    /* Copy and free the previous table array */
513
514    if (AcpiGbl_RootTableList.Tables)
515    {
516        memcpy (Tables, AcpiGbl_RootTableList.Tables,
517            (ACPI_SIZE) TableCount * sizeof (ACPI_TABLE_DESC));
518
519        if (AcpiGbl_RootTableList.Flags & ACPI_ROOT_ORIGIN_ALLOCATED)
520        {
521            ACPI_FREE (AcpiGbl_RootTableList.Tables);
522        }
523    }
524
525    AcpiGbl_RootTableList.Tables = Tables;
526    AcpiGbl_RootTableList.MaxTableCount =
527        TableCount + ACPI_ROOT_TABLE_SIZE_INCREMENT;
528    AcpiGbl_RootTableList.Flags |= ACPI_ROOT_ORIGIN_ALLOCATED;
529
530    return_ACPI_STATUS (AE_OK);
531}
532
533
534/*******************************************************************************
535 *
536 * FUNCTION:    AcpiTbGetNextTableDescriptor
537 *
538 * PARAMETERS:  TableIndex          - Where table index is returned
539 *              TableDesc           - Where table descriptor is returned
540 *
541 * RETURN:      Status and table index/descriptor.
542 *
543 * DESCRIPTION: Allocate a new ACPI table entry to the global table list
544 *
545 ******************************************************************************/
546
547ACPI_STATUS
548AcpiTbGetNextTableDescriptor (
549    UINT32                  *TableIndex,
550    ACPI_TABLE_DESC         **TableDesc)
551{
552    ACPI_STATUS             Status;
553    UINT32                  i;
554
555
556    /* Ensure that there is room for the table in the Root Table List */
557
558    if (AcpiGbl_RootTableList.CurrentTableCount >=
559        AcpiGbl_RootTableList.MaxTableCount)
560    {
561        Status = AcpiTbResizeRootTableList();
562        if (ACPI_FAILURE (Status))
563        {
564            return (Status);
565        }
566    }
567
568    i = AcpiGbl_RootTableList.CurrentTableCount;
569    AcpiGbl_RootTableList.CurrentTableCount++;
570
571    if (TableIndex)
572    {
573        *TableIndex = i;
574    }
575    if (TableDesc)
576    {
577        *TableDesc = &AcpiGbl_RootTableList.Tables[i];
578    }
579
580    return (AE_OK);
581}
582
583
584/*******************************************************************************
585 *
586 * FUNCTION:    AcpiTbTerminate
587 *
588 * PARAMETERS:  None
589 *
590 * RETURN:      None
591 *
592 * DESCRIPTION: Delete all internal ACPI tables
593 *
594 ******************************************************************************/
595
596void
597AcpiTbTerminate (
598    void)
599{
600    UINT32                  i;
601
602
603    ACPI_FUNCTION_TRACE (TbTerminate);
604
605
606    (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
607
608    /* Delete the individual tables */
609
610    for (i = 0; i < AcpiGbl_RootTableList.CurrentTableCount; i++)
611    {
612        AcpiTbUninstallTable (&AcpiGbl_RootTableList.Tables[i]);
613    }
614
615    /*
616     * Delete the root table array if allocated locally. Array cannot be
617     * mapped, so we don't need to check for that flag.
618     */
619    if (AcpiGbl_RootTableList.Flags & ACPI_ROOT_ORIGIN_ALLOCATED)
620    {
621        ACPI_FREE (AcpiGbl_RootTableList.Tables);
622    }
623
624    AcpiGbl_RootTableList.Tables = NULL;
625    AcpiGbl_RootTableList.Flags = 0;
626    AcpiGbl_RootTableList.CurrentTableCount = 0;
627
628    ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "ACPI Tables freed\n"));
629
630    (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
631    return_VOID;
632}
633
634
635/*******************************************************************************
636 *
637 * FUNCTION:    AcpiTbDeleteNamespaceByOwner
638 *
639 * PARAMETERS:  TableIndex          - Table index
640 *
641 * RETURN:      Status
642 *
643 * DESCRIPTION: Delete all namespace objects created when this table was loaded.
644 *
645 ******************************************************************************/
646
647ACPI_STATUS
648AcpiTbDeleteNamespaceByOwner (
649    UINT32                  TableIndex)
650{
651    ACPI_OWNER_ID           OwnerId;
652    ACPI_STATUS             Status;
653
654
655    ACPI_FUNCTION_TRACE (TbDeleteNamespaceByOwner);
656
657
658    Status = AcpiUtAcquireMutex (ACPI_MTX_TABLES);
659    if (ACPI_FAILURE (Status))
660    {
661        return_ACPI_STATUS (Status);
662    }
663
664    if (TableIndex >= AcpiGbl_RootTableList.CurrentTableCount)
665    {
666        /* The table index does not exist */
667
668        (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
669        return_ACPI_STATUS (AE_NOT_EXIST);
670    }
671
672    /* Get the owner ID for this table, used to delete namespace nodes */
673
674    OwnerId = AcpiGbl_RootTableList.Tables[TableIndex].OwnerId;
675    (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
676
677    /*
678     * Need to acquire the namespace writer lock to prevent interference
679     * with any concurrent namespace walks. The interpreter must be
680     * released during the deletion since the acquisition of the deletion
681     * lock may block, and also since the execution of a namespace walk
682     * must be allowed to use the interpreter.
683     */
684    Status = AcpiUtAcquireWriteLock (&AcpiGbl_NamespaceRwLock);
685    if (ACPI_FAILURE (Status))
686    {
687        return_ACPI_STATUS (Status);
688    }
689    AcpiNsDeleteNamespaceByOwner (OwnerId);
690    AcpiUtReleaseWriteLock (&AcpiGbl_NamespaceRwLock);
691    return_ACPI_STATUS (Status);
692}
693
694
695/*******************************************************************************
696 *
697 * FUNCTION:    AcpiTbAllocateOwnerId
698 *
699 * PARAMETERS:  TableIndex          - Table index
700 *
701 * RETURN:      Status
702 *
703 * DESCRIPTION: Allocates OwnerId in TableDesc
704 *
705 ******************************************************************************/
706
707ACPI_STATUS
708AcpiTbAllocateOwnerId (
709    UINT32                  TableIndex)
710{
711    ACPI_STATUS             Status = AE_BAD_PARAMETER;
712
713
714    ACPI_FUNCTION_TRACE (TbAllocateOwnerId);
715
716
717    (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
718    if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount)
719    {
720        Status = AcpiUtAllocateOwnerId (
721            &(AcpiGbl_RootTableList.Tables[TableIndex].OwnerId));
722    }
723
724    (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
725    return_ACPI_STATUS (Status);
726}
727
728
729/*******************************************************************************
730 *
731 * FUNCTION:    AcpiTbReleaseOwnerId
732 *
733 * PARAMETERS:  TableIndex          - Table index
734 *
735 * RETURN:      Status
736 *
737 * DESCRIPTION: Releases OwnerId in TableDesc
738 *
739 ******************************************************************************/
740
741ACPI_STATUS
742AcpiTbReleaseOwnerId (
743    UINT32                  TableIndex)
744{
745    ACPI_STATUS             Status = AE_BAD_PARAMETER;
746
747
748    ACPI_FUNCTION_TRACE (TbReleaseOwnerId);
749
750
751    (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
752    if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount)
753    {
754        AcpiUtReleaseOwnerId (
755            &(AcpiGbl_RootTableList.Tables[TableIndex].OwnerId));
756        Status = AE_OK;
757    }
758
759    (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
760    return_ACPI_STATUS (Status);
761}
762
763
764/*******************************************************************************
765 *
766 * FUNCTION:    AcpiTbGetOwnerId
767 *
768 * PARAMETERS:  TableIndex          - Table index
769 *              OwnerId             - Where the table OwnerId is returned
770 *
771 * RETURN:      Status
772 *
773 * DESCRIPTION: returns OwnerId for the ACPI table
774 *
775 ******************************************************************************/
776
777ACPI_STATUS
778AcpiTbGetOwnerId (
779    UINT32                  TableIndex,
780    ACPI_OWNER_ID           *OwnerId)
781{
782    ACPI_STATUS             Status = AE_BAD_PARAMETER;
783
784
785    ACPI_FUNCTION_TRACE (TbGetOwnerId);
786
787
788    (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
789    if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount)
790    {
791        *OwnerId = AcpiGbl_RootTableList.Tables[TableIndex].OwnerId;
792        Status = AE_OK;
793    }
794
795    (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
796    return_ACPI_STATUS (Status);
797}
798
799
800/*******************************************************************************
801 *
802 * FUNCTION:    AcpiTbIsTableLoaded
803 *
804 * PARAMETERS:  TableIndex          - Index into the root table
805 *
806 * RETURN:      Table Loaded Flag
807 *
808 ******************************************************************************/
809
810BOOLEAN
811AcpiTbIsTableLoaded (
812    UINT32                  TableIndex)
813{
814    BOOLEAN                 IsLoaded = FALSE;
815
816
817    (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
818    if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount)
819    {
820        IsLoaded = (BOOLEAN)
821            (AcpiGbl_RootTableList.Tables[TableIndex].Flags &
822            ACPI_TABLE_IS_LOADED);
823    }
824
825    (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
826    return (IsLoaded);
827}
828
829
830/*******************************************************************************
831 *
832 * FUNCTION:    AcpiTbSetTableLoadedFlag
833 *
834 * PARAMETERS:  TableIndex          - Table index
835 *              IsLoaded            - TRUE if table is loaded, FALSE otherwise
836 *
837 * RETURN:      None
838 *
839 * DESCRIPTION: Sets the table loaded flag to either TRUE or FALSE.
840 *
841 ******************************************************************************/
842
843void
844AcpiTbSetTableLoadedFlag (
845    UINT32                  TableIndex,
846    BOOLEAN                 IsLoaded)
847{
848
849    (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
850    if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount)
851    {
852        if (IsLoaded)
853        {
854            AcpiGbl_RootTableList.Tables[TableIndex].Flags |=
855                ACPI_TABLE_IS_LOADED;
856        }
857        else
858        {
859            AcpiGbl_RootTableList.Tables[TableIndex].Flags &=
860                ~ACPI_TABLE_IS_LOADED;
861        }
862    }
863
864    (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
865}
866
867
868/*******************************************************************************
869 *
870 * FUNCTION:    AcpiTbLoadTable
871 *
872 * PARAMETERS:  TableIndex              - Table index
873 *              ParentNode              - Where table index is returned
874 *
875 * RETURN:      Status
876 *
877 * DESCRIPTION: Load an ACPI table
878 *
879 ******************************************************************************/
880
881ACPI_STATUS
882AcpiTbLoadTable (
883    UINT32                  TableIndex,
884    ACPI_NAMESPACE_NODE     *ParentNode)
885{
886    ACPI_TABLE_HEADER       *Table;
887    ACPI_STATUS             Status;
888    ACPI_OWNER_ID           OwnerId;
889
890
891    ACPI_FUNCTION_TRACE (TbLoadTable);
892
893
894    /*
895     * Note: Now table is "INSTALLED", it must be validated before
896     * using.
897     */
898    Status = AcpiGetTableByIndex (TableIndex, &Table);
899    if (ACPI_FAILURE (Status))
900    {
901        return_ACPI_STATUS (Status);
902    }
903
904    Status = AcpiNsLoadTable (TableIndex, ParentNode);
905
906    /* Execute any module-level code that was found in the table */
907
908    if (!AcpiGbl_ParseTableAsTermList && AcpiGbl_GroupModuleLevelCode)
909    {
910        AcpiNsExecModuleCodeList ();
911    }
912
913    /*
914     * Update GPEs for any new _Lxx/_Exx methods. Ignore errors. The host is
915     * responsible for discovering any new wake GPEs by running _PRW methods
916     * that may have been loaded by this table.
917     */
918    Status = AcpiTbGetOwnerId (TableIndex, &OwnerId);
919    if (ACPI_SUCCESS (Status))
920    {
921        AcpiEvUpdateGpes (OwnerId);
922    }
923
924    /* Invoke table handler if present */
925
926    if (AcpiGbl_TableHandler)
927    {
928        (void) AcpiGbl_TableHandler (ACPI_TABLE_EVENT_LOAD, Table,
929            AcpiGbl_TableHandlerContext);
930    }
931
932    return_ACPI_STATUS (Status);
933}
934
935
936/*******************************************************************************
937 *
938 * FUNCTION:    AcpiTbInstallAndLoadTable
939 *
940 * PARAMETERS:  Table                   - Pointer to the table
941 *              Address                 - Physical address of the table
942 *              Flags                   - Allocation flags of the table
943 *              TableIndex              - Where table index is returned
944 *
945 * RETURN:      Status
946 *
947 * DESCRIPTION: Install and load an ACPI table
948 *
949 ******************************************************************************/
950
951ACPI_STATUS
952AcpiTbInstallAndLoadTable (
953    ACPI_TABLE_HEADER       *Table,
954    ACPI_PHYSICAL_ADDRESS   Address,
955    UINT8                   Flags,
956    BOOLEAN                 Override,
957    UINT32                  *TableIndex)
958{
959    ACPI_STATUS             Status;
960    UINT32                  i;
961    ACPI_OWNER_ID           OwnerId;
962
963
964    ACPI_FUNCTION_TRACE (AcpiLoadTable);
965
966
967    (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
968
969    /* Install the table and load it into the namespace */
970
971    Status = AcpiTbInstallStandardTable (Address, Flags, TRUE,
972        Override, &i);
973    if (ACPI_FAILURE (Status))
974    {
975        goto UnlockAndExit;
976    }
977
978    /*
979     * Note: Now table is "INSTALLED", it must be validated before
980     * using.
981     */
982    Status = AcpiTbValidateTable (&AcpiGbl_RootTableList.Tables[i]);
983    if (ACPI_FAILURE (Status))
984    {
985        goto UnlockAndExit;
986    }
987
988    (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
989    Status = AcpiNsLoadTable (i, AcpiGbl_RootNode);
990
991    /* Execute any module-level code that was found in the table */
992
993    if (!AcpiGbl_ParseTableAsTermList && AcpiGbl_GroupModuleLevelCode)
994    {
995        AcpiNsExecModuleCodeList ();
996    }
997
998    /*
999     * Update GPEs for any new _Lxx/_Exx methods. Ignore errors. The host is
1000     * responsible for discovering any new wake GPEs by running _PRW methods
1001     * that may have been loaded by this table.
1002     */
1003    Status = AcpiTbGetOwnerId (i, &OwnerId);
1004    if (ACPI_SUCCESS (Status))
1005    {
1006        AcpiEvUpdateGpes (OwnerId);
1007    }
1008
1009    /* Invoke table handler if present */
1010
1011    if (AcpiGbl_TableHandler)
1012    {
1013        (void) AcpiGbl_TableHandler (ACPI_TABLE_EVENT_LOAD, Table,
1014            AcpiGbl_TableHandlerContext);
1015    }
1016    (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
1017
1018UnlockAndExit:
1019    *TableIndex = i;
1020    (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
1021    return_ACPI_STATUS (Status);
1022}
1023