1 /******************************************************************************
3 * Module Name: tbdata - Table manager data structure functions
5 *****************************************************************************/
8 * Copyright (C) 2000 - 2014, 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 ACPI_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, TableDesc->Address);
132 /* Table is not valid yet */
136 return (AE_NO_MEMORY);
139 /* Fill the return values */
142 *TableLength = TableDesc->Length;
143 *TableFlags = TableDesc->Flags;
148 /*******************************************************************************
150 * FUNCTION: AcpiTbReleaseTable
152 * PARAMETERS: Table - Pointer for the table
153 * TableLength - Length for the table
154 * TableFlags - Allocation flags for the table
158 * DESCRIPTION: Release a table. The inverse of AcpiTbAcquireTable().
160 ******************************************************************************/
164 ACPI_TABLE_HEADER *Table,
169 switch (TableFlags & ACPI_TABLE_ORIGIN_MASK)
171 case ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL:
173 AcpiOsUnmapMemory (Table, TableLength);
176 case ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL:
177 case ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL:
185 /*******************************************************************************
187 * FUNCTION: AcpiTbAcquireTempTable
189 * PARAMETERS: TableDesc - Table descriptor to be acquired
190 * Address - Address of the table
191 * Flags - Allocation flags of the table
195 * DESCRIPTION: This function validates the table header to obtain the length
196 * of a table and fills the table descriptor to make its state as
197 * "INSTALLED". Such a table descriptor is only used for verified
200 ******************************************************************************/
203 AcpiTbAcquireTempTable (
204 ACPI_TABLE_DESC *TableDesc,
205 ACPI_PHYSICAL_ADDRESS Address,
208 ACPI_TABLE_HEADER *TableHeader;
211 switch (Flags & ACPI_TABLE_ORIGIN_MASK)
213 case ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL:
215 /* Get the length of the full table from the header */
217 TableHeader = AcpiOsMapMemory (Address, sizeof (ACPI_TABLE_HEADER));
220 return (AE_NO_MEMORY);
223 AcpiTbInitTableDescriptor (TableDesc, Address, Flags, TableHeader);
224 AcpiOsUnmapMemory (TableHeader, sizeof (ACPI_TABLE_HEADER));
227 case ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL:
228 case ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL:
230 TableHeader = ACPI_CAST_PTR (ACPI_TABLE_HEADER, Address);
233 return (AE_NO_MEMORY);
236 AcpiTbInitTableDescriptor (TableDesc, Address, Flags, TableHeader);
244 /* Table is not valid yet */
246 return (AE_NO_MEMORY);
250 /*******************************************************************************
252 * FUNCTION: AcpiTbReleaseTempTable
254 * PARAMETERS: TableDesc - Table descriptor to be released
258 * DESCRIPTION: The inverse of AcpiTbAcquireTempTable().
260 *****************************************************************************/
263 AcpiTbReleaseTempTable (
264 ACPI_TABLE_DESC *TableDesc)
268 * Note that the .Address is maintained by the callers of
269 * AcpiTbAcquireTempTable(), thus do not invoke AcpiTbUninstallTable()
270 * where .Address will be freed.
272 AcpiTbInvalidateTable (TableDesc);
276 /******************************************************************************
278 * FUNCTION: AcpiTbValidateTable
280 * PARAMETERS: TableDesc - Table descriptor
284 * DESCRIPTION: This function is called to validate the table, the returned
285 * table descriptor is in "VALIDATED" state.
287 *****************************************************************************/
290 AcpiTbValidateTable (
291 ACPI_TABLE_DESC *TableDesc)
293 ACPI_STATUS Status = AE_OK;
296 ACPI_FUNCTION_TRACE (TbValidateTable);
299 /* Validate the table if necessary */
301 if (!TableDesc->Pointer)
303 Status = AcpiTbAcquireTable (TableDesc, &TableDesc->Pointer,
304 &TableDesc->Length, &TableDesc->Flags);
305 if (!TableDesc->Pointer)
307 Status = AE_NO_MEMORY;
311 return_ACPI_STATUS (Status);
315 /*******************************************************************************
317 * FUNCTION: AcpiTbInvalidateTable
319 * PARAMETERS: TableDesc - Table descriptor
323 * DESCRIPTION: Invalidate one internal ACPI table, this is the inverse of
324 * AcpiTbValidateTable().
326 ******************************************************************************/
329 AcpiTbInvalidateTable (
330 ACPI_TABLE_DESC *TableDesc)
333 ACPI_FUNCTION_TRACE (TbInvalidateTable);
336 /* Table must be validated */
338 if (!TableDesc->Pointer)
343 AcpiTbReleaseTable (TableDesc->Pointer, TableDesc->Length,
345 TableDesc->Pointer = NULL;
351 /******************************************************************************
353 * FUNCTION: AcpiTbValidateTempTable
355 * PARAMETERS: TableDesc - Table descriptor
359 * DESCRIPTION: This function is called to validate the table, the returned
360 * table descriptor is in "VALIDATED" state.
362 *****************************************************************************/
365 AcpiTbValidateTempTable (
366 ACPI_TABLE_DESC *TableDesc)
369 if (!TableDesc->Pointer && !AcpiGbl_VerifyTableChecksum)
372 * Only validates the header of the table.
373 * Note that Length contains the size of the mapping after invoking
374 * this work around, this value is required by
375 * AcpiTbReleaseTempTable().
376 * We can do this because in AcpiInitTableDescriptor(), the Length
377 * field of the installed descriptor is filled with the actual
378 * table length obtaining from the table header.
380 TableDesc->Length = sizeof (ACPI_TABLE_HEADER);
383 return (AcpiTbValidateTable (TableDesc));
387 /******************************************************************************
389 * FUNCTION: AcpiTbVerifyTempTable
391 * PARAMETERS: TableDesc - Table descriptor
392 * Signature - Table signature to verify
396 * DESCRIPTION: This function is called to validate and verify the table, the
397 * returned table descriptor is in "VALIDATED" state.
399 *****************************************************************************/
402 AcpiTbVerifyTempTable (
403 ACPI_TABLE_DESC *TableDesc,
406 ACPI_STATUS Status = AE_OK;
409 ACPI_FUNCTION_TRACE (TbVerifyTempTable);
412 /* Validate the table */
414 Status = AcpiTbValidateTempTable (TableDesc);
415 if (ACPI_FAILURE (Status))
417 return_ACPI_STATUS (AE_NO_MEMORY);
420 /* If a particular signature is expected (DSDT/FACS), it must match */
423 !ACPI_COMPARE_NAME (&TableDesc->Signature, Signature))
425 ACPI_BIOS_ERROR ((AE_INFO,
426 "Invalid signature 0x%X for ACPI table, expected [%s]",
427 TableDesc->Signature.Integer, Signature));
428 Status = AE_BAD_SIGNATURE;
429 goto InvalidateAndExit;
432 /* Verify the checksum */
434 if (AcpiGbl_VerifyTableChecksum)
436 Status = AcpiTbVerifyChecksum (TableDesc->Pointer, TableDesc->Length);
437 if (ACPI_FAILURE (Status))
439 ACPI_EXCEPTION ((AE_INFO, AE_NO_MEMORY,
440 "%4.4s " ACPI_PRINTF_UINT
441 " Attempted table install failed",
442 AcpiUtValidAcpiName (TableDesc->Signature.Ascii) ?
443 TableDesc->Signature.Ascii : "????",
444 ACPI_FORMAT_TO_UINT (TableDesc->Address)));
445 goto InvalidateAndExit;
449 return_ACPI_STATUS (AE_OK);
452 AcpiTbInvalidateTable (TableDesc);
453 return_ACPI_STATUS (Status);
457 /*******************************************************************************
459 * FUNCTION: AcpiTbResizeRootTableList
465 * DESCRIPTION: Expand the size of global table array
467 ******************************************************************************/
470 AcpiTbResizeRootTableList (
473 ACPI_TABLE_DESC *Tables;
477 ACPI_FUNCTION_TRACE (TbResizeRootTableList);
480 /* AllowResize flag is a parameter to AcpiInitializeTables */
482 if (!(AcpiGbl_RootTableList.Flags & ACPI_ROOT_ALLOW_RESIZE))
484 ACPI_ERROR ((AE_INFO, "Resize of Root Table Array is not allowed"));
485 return_ACPI_STATUS (AE_SUPPORT);
488 /* Increase the Table Array size */
490 if (AcpiGbl_RootTableList.Flags & ACPI_ROOT_ORIGIN_ALLOCATED)
492 TableCount = AcpiGbl_RootTableList.MaxTableCount;
496 TableCount = AcpiGbl_RootTableList.CurrentTableCount;
499 Tables = ACPI_ALLOCATE_ZEROED (
500 ((ACPI_SIZE) TableCount + ACPI_ROOT_TABLE_SIZE_INCREMENT) *
501 sizeof (ACPI_TABLE_DESC));
504 ACPI_ERROR ((AE_INFO, "Could not allocate new root table array"));
505 return_ACPI_STATUS (AE_NO_MEMORY);
508 /* Copy and free the previous table array */
510 if (AcpiGbl_RootTableList.Tables)
512 ACPI_MEMCPY (Tables, AcpiGbl_RootTableList.Tables,
513 (ACPI_SIZE) TableCount * sizeof (ACPI_TABLE_DESC));
515 if (AcpiGbl_RootTableList.Flags & ACPI_ROOT_ORIGIN_ALLOCATED)
517 ACPI_FREE (AcpiGbl_RootTableList.Tables);
521 AcpiGbl_RootTableList.Tables = Tables;
522 AcpiGbl_RootTableList.MaxTableCount =
523 TableCount + ACPI_ROOT_TABLE_SIZE_INCREMENT;
524 AcpiGbl_RootTableList.Flags |= ACPI_ROOT_ORIGIN_ALLOCATED;
526 return_ACPI_STATUS (AE_OK);
530 /*******************************************************************************
532 * FUNCTION: AcpiTbGetNextRootIndex
534 * PARAMETERS: TableIndex - Where table index is returned
536 * RETURN: Status and table index.
538 * DESCRIPTION: Allocate a new ACPI table entry to the global table list
540 ******************************************************************************/
543 AcpiTbGetNextRootIndex (
549 /* Ensure that there is room for the table in the Root Table List */
551 if (AcpiGbl_RootTableList.CurrentTableCount >=
552 AcpiGbl_RootTableList.MaxTableCount)
554 Status = AcpiTbResizeRootTableList();
555 if (ACPI_FAILURE (Status))
561 *TableIndex = AcpiGbl_RootTableList.CurrentTableCount;
562 AcpiGbl_RootTableList.CurrentTableCount++;
567 /*******************************************************************************
569 * FUNCTION: AcpiTbTerminate
575 * DESCRIPTION: Delete all internal ACPI tables
577 ******************************************************************************/
586 ACPI_FUNCTION_TRACE (TbTerminate);
589 (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
591 /* Delete the individual tables */
593 for (i = 0; i < AcpiGbl_RootTableList.CurrentTableCount; i++)
595 AcpiTbUninstallTable (&AcpiGbl_RootTableList.Tables[i]);
599 * Delete the root table array if allocated locally. Array cannot be
600 * mapped, so we don't need to check for that flag.
602 if (AcpiGbl_RootTableList.Flags & ACPI_ROOT_ORIGIN_ALLOCATED)
604 ACPI_FREE (AcpiGbl_RootTableList.Tables);
607 AcpiGbl_RootTableList.Tables = NULL;
608 AcpiGbl_RootTableList.Flags = 0;
609 AcpiGbl_RootTableList.CurrentTableCount = 0;
611 ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "ACPI Tables freed\n"));
613 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
618 /*******************************************************************************
620 * FUNCTION: AcpiTbDeleteNamespaceByOwner
622 * PARAMETERS: TableIndex - Table index
626 * DESCRIPTION: Delete all namespace objects created when this table was loaded.
628 ******************************************************************************/
631 AcpiTbDeleteNamespaceByOwner (
634 ACPI_OWNER_ID OwnerId;
638 ACPI_FUNCTION_TRACE (TbDeleteNamespaceByOwner);
641 Status = AcpiUtAcquireMutex (ACPI_MTX_TABLES);
642 if (ACPI_FAILURE (Status))
644 return_ACPI_STATUS (Status);
647 if (TableIndex >= AcpiGbl_RootTableList.CurrentTableCount)
649 /* The table index does not exist */
651 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
652 return_ACPI_STATUS (AE_NOT_EXIST);
655 /* Get the owner ID for this table, used to delete namespace nodes */
657 OwnerId = AcpiGbl_RootTableList.Tables[TableIndex].OwnerId;
658 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
661 * Need to acquire the namespace writer lock to prevent interference
662 * with any concurrent namespace walks. The interpreter must be
663 * released during the deletion since the acquisition of the deletion
664 * lock may block, and also since the execution of a namespace walk
665 * must be allowed to use the interpreter.
667 (void) AcpiUtReleaseMutex (ACPI_MTX_INTERPRETER);
668 Status = AcpiUtAcquireWriteLock (&AcpiGbl_NamespaceRwLock);
670 AcpiNsDeleteNamespaceByOwner (OwnerId);
671 if (ACPI_FAILURE (Status))
673 return_ACPI_STATUS (Status);
676 AcpiUtReleaseWriteLock (&AcpiGbl_NamespaceRwLock);
678 Status = AcpiUtAcquireMutex (ACPI_MTX_INTERPRETER);
679 return_ACPI_STATUS (Status);
683 /*******************************************************************************
685 * FUNCTION: AcpiTbAllocateOwnerId
687 * PARAMETERS: TableIndex - Table index
691 * DESCRIPTION: Allocates OwnerId in TableDesc
693 ******************************************************************************/
696 AcpiTbAllocateOwnerId (
699 ACPI_STATUS Status = AE_BAD_PARAMETER;
702 ACPI_FUNCTION_TRACE (TbAllocateOwnerId);
705 (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
706 if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount)
708 Status = AcpiUtAllocateOwnerId (
709 &(AcpiGbl_RootTableList.Tables[TableIndex].OwnerId));
712 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
713 return_ACPI_STATUS (Status);
717 /*******************************************************************************
719 * FUNCTION: AcpiTbReleaseOwnerId
721 * PARAMETERS: TableIndex - Table index
725 * DESCRIPTION: Releases OwnerId in TableDesc
727 ******************************************************************************/
730 AcpiTbReleaseOwnerId (
733 ACPI_STATUS Status = AE_BAD_PARAMETER;
736 ACPI_FUNCTION_TRACE (TbReleaseOwnerId);
739 (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
740 if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount)
742 AcpiUtReleaseOwnerId (
743 &(AcpiGbl_RootTableList.Tables[TableIndex].OwnerId));
747 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
748 return_ACPI_STATUS (Status);
752 /*******************************************************************************
754 * FUNCTION: AcpiTbGetOwnerId
756 * PARAMETERS: TableIndex - Table index
757 * OwnerId - Where the table OwnerId is returned
761 * DESCRIPTION: returns OwnerId for the ACPI table
763 ******************************************************************************/
768 ACPI_OWNER_ID *OwnerId)
770 ACPI_STATUS Status = AE_BAD_PARAMETER;
773 ACPI_FUNCTION_TRACE (TbGetOwnerId);
776 (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
777 if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount)
779 *OwnerId = AcpiGbl_RootTableList.Tables[TableIndex].OwnerId;
783 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
784 return_ACPI_STATUS (Status);
788 /*******************************************************************************
790 * FUNCTION: AcpiTbIsTableLoaded
792 * PARAMETERS: TableIndex - Index into the root table
794 * RETURN: Table Loaded Flag
796 ******************************************************************************/
799 AcpiTbIsTableLoaded (
802 BOOLEAN IsLoaded = FALSE;
805 (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
806 if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount)
809 (AcpiGbl_RootTableList.Tables[TableIndex].Flags &
810 ACPI_TABLE_IS_LOADED);
813 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);
818 /*******************************************************************************
820 * FUNCTION: AcpiTbSetTableLoadedFlag
822 * PARAMETERS: TableIndex - Table index
823 * IsLoaded - TRUE if table is loaded, FALSE otherwise
827 * DESCRIPTION: Sets the table loaded flag to either TRUE or FALSE.
829 ******************************************************************************/
832 AcpiTbSetTableLoadedFlag (
837 (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES);
838 if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount)
842 AcpiGbl_RootTableList.Tables[TableIndex].Flags |=
843 ACPI_TABLE_IS_LOADED;
847 AcpiGbl_RootTableList.Tables[TableIndex].Flags &=
848 ~ACPI_TABLE_IS_LOADED;
852 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES);