1 /******************************************************************************
3 * Module Name: tbdata - Table manager data structure functions
5 *****************************************************************************/
8 * Copyright (C) 2000 - 2016, Intel Corp.
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
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.
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.
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.
49 #define _COMPONENT ACPI_TABLES
50 ACPI_MODULE_NAME ("tbdata")
53 /*******************************************************************************
55 * FUNCTION: AcpiTbInitTableDescriptor
57 * PARAMETERS: TableDesc - Table descriptor
58 * Address - Physical address of the table
59 * Flags - Allocation flags of the table
60 * Table - Pointer to the table
64 * DESCRIPTION: Initialize a new table descriptor
66 ******************************************************************************/
69 AcpiTbInitTableDescriptor (
70 ACPI_TABLE_DESC
*TableDesc
,
71 ACPI_PHYSICAL_ADDRESS Address
,
73 ACPI_TABLE_HEADER
*Table
)
77 * Initialize the table descriptor. Set the pointer to NULL, since the
78 * table is not fully mapped at this time.
80 memset (TableDesc
, 0, sizeof (ACPI_TABLE_DESC
));
81 TableDesc
->Address
= Address
;
82 TableDesc
->Length
= Table
->Length
;
83 TableDesc
->Flags
= Flags
;
84 ACPI_MOVE_32_TO_32 (TableDesc
->Signature
.Ascii
, Table
->Signature
);
88 /*******************************************************************************
90 * FUNCTION: AcpiTbAcquireTable
92 * PARAMETERS: TableDesc - Table descriptor
93 * TablePtr - Where table is returned
94 * TableLength - Where table length is returned
95 * TableFlags - Where table allocation flags are returned
99 * DESCRIPTION: Acquire an ACPI table. It can be used for tables not
100 * maintained in the AcpiGbl_RootTableList.
102 ******************************************************************************/
106 ACPI_TABLE_DESC
*TableDesc
,
107 ACPI_TABLE_HEADER
**TablePtr
,
111 ACPI_TABLE_HEADER
*Table
= NULL
;
114 switch (TableDesc
->Flags
& ACPI_TABLE_ORIGIN_MASK
)
116 case ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL
:
118 Table
= AcpiOsMapMemory (TableDesc
->Address
, TableDesc
->Length
);
121 case ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL
:
122 case ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL
:
124 Table
= ACPI_CAST_PTR (ACPI_TABLE_HEADER
,
125 ACPI_PHYSADDR_TO_PTR (TableDesc
->Address
));
133 /* Table is not valid yet */
137 return (AE_NO_MEMORY
);
140 /* Fill the return values */
143 *TableLength
= TableDesc
->Length
;
144 *TableFlags
= TableDesc
->Flags
;
149 /*******************************************************************************
151 * FUNCTION: AcpiTbReleaseTable
153 * PARAMETERS: Table - Pointer for the table
154 * TableLength - Length for the table
155 * TableFlags - Allocation flags for the table
159 * DESCRIPTION: Release a table. The inverse of AcpiTbAcquireTable().
161 ******************************************************************************/
165 ACPI_TABLE_HEADER
*Table
,
170 switch (TableFlags
& ACPI_TABLE_ORIGIN_MASK
)
172 case ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL
:
174 AcpiOsUnmapMemory (Table
, TableLength
);
177 case ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL
:
178 case ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL
:
186 /*******************************************************************************
188 * FUNCTION: AcpiTbAcquireTempTable
190 * PARAMETERS: TableDesc - Table descriptor to be acquired
191 * Address - Address of the table
192 * Flags - Allocation flags of the table
196 * DESCRIPTION: This function validates the table header to obtain the length
197 * of a table and fills the table descriptor to make its state as
198 * "INSTALLED". Such a table descriptor is only used for verified
201 ******************************************************************************/
204 AcpiTbAcquireTempTable (
205 ACPI_TABLE_DESC
*TableDesc
,
206 ACPI_PHYSICAL_ADDRESS Address
,
209 ACPI_TABLE_HEADER
*TableHeader
;
212 switch (Flags
& ACPI_TABLE_ORIGIN_MASK
)
214 case ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL
:
216 /* Get the length of the full table from the header */
218 TableHeader
= AcpiOsMapMemory (Address
, sizeof (ACPI_TABLE_HEADER
));
221 return (AE_NO_MEMORY
);
224 AcpiTbInitTableDescriptor (TableDesc
, Address
, Flags
, TableHeader
);
225 AcpiOsUnmapMemory (TableHeader
, sizeof (ACPI_TABLE_HEADER
));
228 case ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL
:
229 case ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL
:
231 TableHeader
= ACPI_CAST_PTR (ACPI_TABLE_HEADER
,
232 ACPI_PHYSADDR_TO_PTR (Address
));
235 return (AE_NO_MEMORY
);
238 AcpiTbInitTableDescriptor (TableDesc
, Address
, Flags
, TableHeader
);
246 /* Table is not valid yet */
248 return (AE_NO_MEMORY
);
252 /*******************************************************************************
254 * FUNCTION: AcpiTbReleaseTempTable
256 * PARAMETERS: TableDesc - Table descriptor to be released
260 * DESCRIPTION: The inverse of AcpiTbAcquireTempTable().
262 *****************************************************************************/
265 AcpiTbReleaseTempTable (
266 ACPI_TABLE_DESC
*TableDesc
)
270 * Note that the .Address is maintained by the callers of
271 * AcpiTbAcquireTempTable(), thus do not invoke AcpiTbUninstallTable()
272 * where .Address will be freed.
274 AcpiTbInvalidateTable (TableDesc
);
278 /******************************************************************************
280 * FUNCTION: AcpiTbValidateTable
282 * PARAMETERS: TableDesc - Table descriptor
286 * DESCRIPTION: This function is called to validate the table, the returned
287 * table descriptor is in "VALIDATED" state.
289 *****************************************************************************/
292 AcpiTbValidateTable (
293 ACPI_TABLE_DESC
*TableDesc
)
295 ACPI_STATUS Status
= AE_OK
;
298 ACPI_FUNCTION_TRACE (TbValidateTable
);
301 /* Validate the table if necessary */
303 if (!TableDesc
->Pointer
)
305 Status
= AcpiTbAcquireTable (TableDesc
, &TableDesc
->Pointer
,
306 &TableDesc
->Length
, &TableDesc
->Flags
);
307 if (!TableDesc
->Pointer
)
309 Status
= AE_NO_MEMORY
;
313 return_ACPI_STATUS (Status
);
317 /*******************************************************************************
319 * FUNCTION: AcpiTbInvalidateTable
321 * PARAMETERS: TableDesc - Table descriptor
325 * DESCRIPTION: Invalidate one internal ACPI table, this is the inverse of
326 * AcpiTbValidateTable().
328 ******************************************************************************/
331 AcpiTbInvalidateTable (
332 ACPI_TABLE_DESC
*TableDesc
)
335 ACPI_FUNCTION_TRACE (TbInvalidateTable
);
338 /* Table must be validated */
340 if (!TableDesc
->Pointer
)
345 AcpiTbReleaseTable (TableDesc
->Pointer
, TableDesc
->Length
,
347 TableDesc
->Pointer
= NULL
;
353 /******************************************************************************
355 * FUNCTION: AcpiTbValidateTempTable
357 * PARAMETERS: TableDesc - Table descriptor
361 * DESCRIPTION: This function is called to validate the table, the returned
362 * table descriptor is in "VALIDATED" state.
364 *****************************************************************************/
367 AcpiTbValidateTempTable (
368 ACPI_TABLE_DESC
*TableDesc
)
371 if (!TableDesc
->Pointer
&& !AcpiGbl_VerifyTableChecksum
)
374 * Only validates the header of the table.
375 * Note that Length contains the size of the mapping after invoking
376 * this work around, this value is required by
377 * AcpiTbReleaseTempTable().
378 * We can do this because in AcpiInitTableDescriptor(), the Length
379 * field of the installed descriptor is filled with the actual
380 * table length obtaining from the table header.
382 TableDesc
->Length
= sizeof (ACPI_TABLE_HEADER
);
385 return (AcpiTbValidateTable (TableDesc
));
389 /******************************************************************************
391 * FUNCTION: AcpiTbVerifyTempTable
393 * PARAMETERS: TableDesc - Table descriptor
394 * Signature - Table signature to verify
398 * DESCRIPTION: This function is called to validate and verify the table, the
399 * returned table descriptor is in "VALIDATED" state.
401 *****************************************************************************/
404 AcpiTbVerifyTempTable (
405 ACPI_TABLE_DESC
*TableDesc
,
408 ACPI_STATUS Status
= AE_OK
;
411 ACPI_FUNCTION_TRACE (TbVerifyTempTable
);
414 /* Validate the table */
416 Status
= AcpiTbValidateTempTable (TableDesc
);
417 if (ACPI_FAILURE (Status
))
419 return_ACPI_STATUS (AE_NO_MEMORY
);
422 /* If a particular signature is expected (DSDT/FACS), it must match */
425 !ACPI_COMPARE_NAME (&TableDesc
->Signature
, Signature
))
427 ACPI_BIOS_ERROR ((AE_INFO
,
428 "Invalid signature 0x%X for ACPI table, expected [%s]",
429 TableDesc
->Signature
.Integer
, Signature
));
430 Status
= AE_BAD_SIGNATURE
;
431 goto InvalidateAndExit
;
434 /* Verify the checksum */
436 if (AcpiGbl_VerifyTableChecksum
)
438 Status
= AcpiTbVerifyChecksum (TableDesc
->Pointer
, TableDesc
->Length
);
439 if (ACPI_FAILURE (Status
))
441 ACPI_EXCEPTION ((AE_INFO
, AE_NO_MEMORY
,
443 " Attempted table install failed",
444 AcpiUtValidNameseg (TableDesc
->Signature
.Ascii
) ?
445 TableDesc
->Signature
.Ascii
: "????",
446 ACPI_FORMAT_UINT64 (TableDesc
->Address
)));
448 goto InvalidateAndExit
;
452 return_ACPI_STATUS (AE_OK
);
455 AcpiTbInvalidateTable (TableDesc
);
456 return_ACPI_STATUS (Status
);
460 /*******************************************************************************
462 * FUNCTION: AcpiTbResizeRootTableList
468 * DESCRIPTION: Expand the size of global table array
470 ******************************************************************************/
473 AcpiTbResizeRootTableList (
476 ACPI_TABLE_DESC
*Tables
;
480 ACPI_FUNCTION_TRACE (TbResizeRootTableList
);
483 /* AllowResize flag is a parameter to AcpiInitializeTables */
485 if (!(AcpiGbl_RootTableList
.Flags
& ACPI_ROOT_ALLOW_RESIZE
))
487 ACPI_ERROR ((AE_INFO
, "Resize of Root Table Array is not allowed"));
488 return_ACPI_STATUS (AE_SUPPORT
);
491 /* Increase the Table Array size */
493 if (AcpiGbl_RootTableList
.Flags
& ACPI_ROOT_ORIGIN_ALLOCATED
)
495 TableCount
= AcpiGbl_RootTableList
.MaxTableCount
;
499 TableCount
= AcpiGbl_RootTableList
.CurrentTableCount
;
502 Tables
= ACPI_ALLOCATE_ZEROED (
503 ((ACPI_SIZE
) TableCount
+ ACPI_ROOT_TABLE_SIZE_INCREMENT
) *
504 sizeof (ACPI_TABLE_DESC
));
507 ACPI_ERROR ((AE_INFO
, "Could not allocate new root table array"));
508 return_ACPI_STATUS (AE_NO_MEMORY
);
511 /* Copy and free the previous table array */
513 if (AcpiGbl_RootTableList
.Tables
)
515 memcpy (Tables
, AcpiGbl_RootTableList
.Tables
,
516 (ACPI_SIZE
) TableCount
* sizeof (ACPI_TABLE_DESC
));
518 if (AcpiGbl_RootTableList
.Flags
& ACPI_ROOT_ORIGIN_ALLOCATED
)
520 ACPI_FREE (AcpiGbl_RootTableList
.Tables
);
524 AcpiGbl_RootTableList
.Tables
= Tables
;
525 AcpiGbl_RootTableList
.MaxTableCount
=
526 TableCount
+ ACPI_ROOT_TABLE_SIZE_INCREMENT
;
527 AcpiGbl_RootTableList
.Flags
|= ACPI_ROOT_ORIGIN_ALLOCATED
;
529 return_ACPI_STATUS (AE_OK
);
533 /*******************************************************************************
535 * FUNCTION: AcpiTbGetNextTableDescriptor
537 * PARAMETERS: TableIndex - Where table index is returned
538 * TableDesc - Where table descriptor is returned
540 * RETURN: Status and table index/descriptor.
542 * DESCRIPTION: Allocate a new ACPI table entry to the global table list
544 ******************************************************************************/
547 AcpiTbGetNextTableDescriptor (
549 ACPI_TABLE_DESC
**TableDesc
)
555 /* Ensure that there is room for the table in the Root Table List */
557 if (AcpiGbl_RootTableList
.CurrentTableCount
>=
558 AcpiGbl_RootTableList
.MaxTableCount
)
560 Status
= AcpiTbResizeRootTableList();
561 if (ACPI_FAILURE (Status
))
567 i
= AcpiGbl_RootTableList
.CurrentTableCount
;
568 AcpiGbl_RootTableList
.CurrentTableCount
++;
576 *TableDesc
= &AcpiGbl_RootTableList
.Tables
[i
];
583 /*******************************************************************************
585 * FUNCTION: AcpiTbTerminate
591 * DESCRIPTION: Delete all internal ACPI tables
593 ******************************************************************************/
602 ACPI_FUNCTION_TRACE (TbTerminate
);
605 (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES
);
607 /* Delete the individual tables */
609 for (i
= 0; i
< AcpiGbl_RootTableList
.CurrentTableCount
; i
++)
611 AcpiTbUninstallTable (&AcpiGbl_RootTableList
.Tables
[i
]);
615 * Delete the root table array if allocated locally. Array cannot be
616 * mapped, so we don't need to check for that flag.
618 if (AcpiGbl_RootTableList
.Flags
& ACPI_ROOT_ORIGIN_ALLOCATED
)
620 ACPI_FREE (AcpiGbl_RootTableList
.Tables
);
623 AcpiGbl_RootTableList
.Tables
= NULL
;
624 AcpiGbl_RootTableList
.Flags
= 0;
625 AcpiGbl_RootTableList
.CurrentTableCount
= 0;
627 ACPI_DEBUG_PRINT ((ACPI_DB_INFO
, "ACPI Tables freed\n"));
629 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES
);
634 /*******************************************************************************
636 * FUNCTION: AcpiTbDeleteNamespaceByOwner
638 * PARAMETERS: TableIndex - Table index
642 * DESCRIPTION: Delete all namespace objects created when this table was loaded.
644 ******************************************************************************/
647 AcpiTbDeleteNamespaceByOwner (
650 ACPI_OWNER_ID OwnerId
;
654 ACPI_FUNCTION_TRACE (TbDeleteNamespaceByOwner
);
657 Status
= AcpiUtAcquireMutex (ACPI_MTX_TABLES
);
658 if (ACPI_FAILURE (Status
))
660 return_ACPI_STATUS (Status
);
663 if (TableIndex
>= AcpiGbl_RootTableList
.CurrentTableCount
)
665 /* The table index does not exist */
667 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES
);
668 return_ACPI_STATUS (AE_NOT_EXIST
);
671 /* Get the owner ID for this table, used to delete namespace nodes */
673 OwnerId
= AcpiGbl_RootTableList
.Tables
[TableIndex
].OwnerId
;
674 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES
);
677 * Need to acquire the namespace writer lock to prevent interference
678 * with any concurrent namespace walks. The interpreter must be
679 * released during the deletion since the acquisition of the deletion
680 * lock may block, and also since the execution of a namespace walk
681 * must be allowed to use the interpreter.
683 (void) AcpiUtReleaseMutex (ACPI_MTX_INTERPRETER
);
684 Status
= AcpiUtAcquireWriteLock (&AcpiGbl_NamespaceRwLock
);
686 AcpiNsDeleteNamespaceByOwner (OwnerId
);
687 if (ACPI_FAILURE (Status
))
689 return_ACPI_STATUS (Status
);
692 AcpiUtReleaseWriteLock (&AcpiGbl_NamespaceRwLock
);
694 Status
= AcpiUtAcquireMutex (ACPI_MTX_INTERPRETER
);
695 return_ACPI_STATUS (Status
);
699 /*******************************************************************************
701 * FUNCTION: AcpiTbAllocateOwnerId
703 * PARAMETERS: TableIndex - Table index
707 * DESCRIPTION: Allocates OwnerId in TableDesc
709 ******************************************************************************/
712 AcpiTbAllocateOwnerId (
715 ACPI_STATUS Status
= AE_BAD_PARAMETER
;
718 ACPI_FUNCTION_TRACE (TbAllocateOwnerId
);
721 (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES
);
722 if (TableIndex
< AcpiGbl_RootTableList
.CurrentTableCount
)
724 Status
= AcpiUtAllocateOwnerId (
725 &(AcpiGbl_RootTableList
.Tables
[TableIndex
].OwnerId
));
728 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES
);
729 return_ACPI_STATUS (Status
);
733 /*******************************************************************************
735 * FUNCTION: AcpiTbReleaseOwnerId
737 * PARAMETERS: TableIndex - Table index
741 * DESCRIPTION: Releases OwnerId in TableDesc
743 ******************************************************************************/
746 AcpiTbReleaseOwnerId (
749 ACPI_STATUS Status
= AE_BAD_PARAMETER
;
752 ACPI_FUNCTION_TRACE (TbReleaseOwnerId
);
755 (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES
);
756 if (TableIndex
< AcpiGbl_RootTableList
.CurrentTableCount
)
758 AcpiUtReleaseOwnerId (
759 &(AcpiGbl_RootTableList
.Tables
[TableIndex
].OwnerId
));
763 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES
);
764 return_ACPI_STATUS (Status
);
768 /*******************************************************************************
770 * FUNCTION: AcpiTbGetOwnerId
772 * PARAMETERS: TableIndex - Table index
773 * OwnerId - Where the table OwnerId is returned
777 * DESCRIPTION: returns OwnerId for the ACPI table
779 ******************************************************************************/
784 ACPI_OWNER_ID
*OwnerId
)
786 ACPI_STATUS Status
= AE_BAD_PARAMETER
;
789 ACPI_FUNCTION_TRACE (TbGetOwnerId
);
792 (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES
);
793 if (TableIndex
< AcpiGbl_RootTableList
.CurrentTableCount
)
795 *OwnerId
= AcpiGbl_RootTableList
.Tables
[TableIndex
].OwnerId
;
799 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES
);
800 return_ACPI_STATUS (Status
);
804 /*******************************************************************************
806 * FUNCTION: AcpiTbIsTableLoaded
808 * PARAMETERS: TableIndex - Index into the root table
810 * RETURN: Table Loaded Flag
812 ******************************************************************************/
815 AcpiTbIsTableLoaded (
818 BOOLEAN IsLoaded
= FALSE
;
821 (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES
);
822 if (TableIndex
< AcpiGbl_RootTableList
.CurrentTableCount
)
825 (AcpiGbl_RootTableList
.Tables
[TableIndex
].Flags
&
826 ACPI_TABLE_IS_LOADED
);
829 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES
);
834 /*******************************************************************************
836 * FUNCTION: AcpiTbSetTableLoadedFlag
838 * PARAMETERS: TableIndex - Table index
839 * IsLoaded - TRUE if table is loaded, FALSE otherwise
843 * DESCRIPTION: Sets the table loaded flag to either TRUE or FALSE.
845 ******************************************************************************/
848 AcpiTbSetTableLoadedFlag (
853 (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES
);
854 if (TableIndex
< AcpiGbl_RootTableList
.CurrentTableCount
)
858 AcpiGbl_RootTableList
.Tables
[TableIndex
].Flags
|=
859 ACPI_TABLE_IS_LOADED
;
863 AcpiGbl_RootTableList
.Tables
[TableIndex
].Flags
&=
864 ~ACPI_TABLE_IS_LOADED
;
868 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES
);