195b482a8SLen Brown /****************************************************************************** 295b482a8SLen Brown * 395b482a8SLen Brown * Module Name: tbinstal - ACPI table installation and removal 495b482a8SLen Brown * 595b482a8SLen Brown *****************************************************************************/ 695b482a8SLen Brown 795b482a8SLen Brown /* 8fbb7a2dcSBob Moore * Copyright (C) 2000 - 2014, Intel Corp. 995b482a8SLen Brown * All rights reserved. 1095b482a8SLen Brown * 1195b482a8SLen Brown * Redistribution and use in source and binary forms, with or without 1295b482a8SLen Brown * modification, are permitted provided that the following conditions 1395b482a8SLen Brown * are met: 1495b482a8SLen Brown * 1. Redistributions of source code must retain the above copyright 1595b482a8SLen Brown * notice, this list of conditions, and the following disclaimer, 1695b482a8SLen Brown * without modification. 1795b482a8SLen Brown * 2. Redistributions in binary form must reproduce at minimum a disclaimer 1895b482a8SLen Brown * substantially similar to the "NO WARRANTY" disclaimer below 1995b482a8SLen Brown * ("Disclaimer") and any redistribution must be conditioned upon 2095b482a8SLen Brown * including a substantially similar Disclaimer requirement for further 2195b482a8SLen Brown * binary redistribution. 2295b482a8SLen Brown * 3. Neither the names of the above-listed copyright holders nor the names 2395b482a8SLen Brown * of any contributors may be used to endorse or promote products derived 2495b482a8SLen Brown * from this software without specific prior written permission. 2595b482a8SLen Brown * 2695b482a8SLen Brown * Alternatively, this software may be distributed under the terms of the 2795b482a8SLen Brown * GNU General Public License ("GPL") version 2 as published by the Free 2895b482a8SLen Brown * Software Foundation. 2995b482a8SLen Brown * 3095b482a8SLen Brown * NO WARRANTY 3195b482a8SLen Brown * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 3295b482a8SLen Brown * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 3395b482a8SLen Brown * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 3495b482a8SLen Brown * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 3595b482a8SLen Brown * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 3695b482a8SLen Brown * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 3795b482a8SLen Brown * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 3895b482a8SLen Brown * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 3995b482a8SLen Brown * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 4095b482a8SLen Brown * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 4195b482a8SLen Brown * POSSIBILITY OF SUCH DAMAGES. 4295b482a8SLen Brown */ 4395b482a8SLen Brown 4495b482a8SLen Brown #include <acpi/acpi.h> 45e2f7a777SLen Brown #include "accommon.h" 46e2f7a777SLen Brown #include "acnamesp.h" 47e2f7a777SLen Brown #include "actables.h" 4895b482a8SLen Brown 4995b482a8SLen Brown #define _COMPONENT ACPI_TABLES 5095b482a8SLen Brown ACPI_MODULE_NAME("tbinstal") 5195b482a8SLen Brown 5286dfc6f3SLv Zheng /* Local prototypes */ 5386dfc6f3SLv Zheng static acpi_status 5486dfc6f3SLv Zheng acpi_tb_acquire_temporal_table(struct acpi_table_desc *table_desc, 5586dfc6f3SLv Zheng acpi_physical_address address, u8 flags); 5686dfc6f3SLv Zheng 5786dfc6f3SLv Zheng static void acpi_tb_release_temporal_table(struct acpi_table_desc *table_desc); 5886dfc6f3SLv Zheng 5986dfc6f3SLv Zheng static acpi_status acpi_tb_acquire_root_table_entry(u32 *table_index); 6086dfc6f3SLv Zheng 6186dfc6f3SLv Zheng static u8 6286dfc6f3SLv Zheng acpi_tb_is_equivalent_table(struct acpi_table_desc *table_desc, 6386dfc6f3SLv Zheng u32 table_index); 6486dfc6f3SLv Zheng 657f9fc99cSLv Zheng /******************************************************************************* 6695b482a8SLen Brown * 677f9fc99cSLv Zheng * FUNCTION: acpi_tb_acquire_table 6895b482a8SLen Brown * 697f9fc99cSLv Zheng * PARAMETERS: table_desc - Table descriptor 707f9fc99cSLv Zheng * table_ptr - Where table is returned 717f9fc99cSLv Zheng * table_length - Where table length is returned 727f9fc99cSLv Zheng * table_flags - Where table allocation flags are returned 7395b482a8SLen Brown * 7495b482a8SLen Brown * RETURN: Status 7595b482a8SLen Brown * 767f9fc99cSLv Zheng * DESCRIPTION: Acquire a table. It can be used for tables not maintained in 777f9fc99cSLv Zheng * acpi_gbl_root_table_list. 7895b482a8SLen Brown * 797f9fc99cSLv Zheng ******************************************************************************/ 8086dfc6f3SLv Zheng 817f9fc99cSLv Zheng acpi_status 827f9fc99cSLv Zheng acpi_tb_acquire_table(struct acpi_table_desc *table_desc, 837f9fc99cSLv Zheng struct acpi_table_header **table_ptr, 847f9fc99cSLv Zheng u32 *table_length, u8 *table_flags) 8595b482a8SLen Brown { 867f9fc99cSLv Zheng struct acpi_table_header *table = NULL; 8795b482a8SLen Brown 88dc156adfSLv Zheng switch (table_desc->flags & ACPI_TABLE_ORIGIN_MASK) { 898a216d7fSLv Zheng case ACPI_TABLE_ORIGIN_INTERN_PHYSICAL: 90dc156adfSLv Zheng 917f9fc99cSLv Zheng table = 927f9fc99cSLv Zheng acpi_os_map_memory(table_desc->address, table_desc->length); 93dc156adfSLv Zheng break; 94dc156adfSLv Zheng 958a216d7fSLv Zheng case ACPI_TABLE_ORIGIN_INTERN_VIRTUAL: 968a216d7fSLv Zheng case ACPI_TABLE_ORIGIN_EXTERN_VIRTUAL: 97dc156adfSLv Zheng 987f9fc99cSLv Zheng table = 99dc156adfSLv Zheng ACPI_CAST_PTR(struct acpi_table_header, 100dc156adfSLv Zheng table_desc->address); 101dc156adfSLv Zheng break; 102dc156adfSLv Zheng 103dc156adfSLv Zheng default: 104dc156adfSLv Zheng 105dc156adfSLv Zheng break; 10695b482a8SLen Brown } 1075582982dSLv Zheng 1087f9fc99cSLv Zheng /* Table is not valid yet */ 1097f9fc99cSLv Zheng 1107f9fc99cSLv Zheng if (!table) { 1117f9fc99cSLv Zheng return (AE_NO_MEMORY); 1127f9fc99cSLv Zheng } 1137f9fc99cSLv Zheng 1147f9fc99cSLv Zheng /* Fill the return values */ 1157f9fc99cSLv Zheng 1167f9fc99cSLv Zheng *table_ptr = table; 1177f9fc99cSLv Zheng *table_length = table_desc->length; 1187f9fc99cSLv Zheng *table_flags = table_desc->flags; 1197f9fc99cSLv Zheng 1207f9fc99cSLv Zheng return (AE_OK); 1217f9fc99cSLv Zheng } 1227f9fc99cSLv Zheng 1237f9fc99cSLv Zheng /******************************************************************************* 1247f9fc99cSLv Zheng * 1257f9fc99cSLv Zheng * FUNCTION: acpi_tb_release_table 1267f9fc99cSLv Zheng * 1277f9fc99cSLv Zheng * PARAMETERS: table - Pointer for the table 1287f9fc99cSLv Zheng * table_length - Length for the table 1297f9fc99cSLv Zheng * table_flags - Allocation flags for the table 1307f9fc99cSLv Zheng * 1317f9fc99cSLv Zheng * RETURN: None 1327f9fc99cSLv Zheng * 1337f9fc99cSLv Zheng * DESCRIPTION: Release a table. The reversal of acpi_tb_acquire_table(). 1347f9fc99cSLv Zheng * 1357f9fc99cSLv Zheng ******************************************************************************/ 1367f9fc99cSLv Zheng 1377f9fc99cSLv Zheng void 1387f9fc99cSLv Zheng acpi_tb_release_table(struct acpi_table_header *table, 1397f9fc99cSLv Zheng u32 table_length, u8 table_flags) 1407f9fc99cSLv Zheng { 1417f9fc99cSLv Zheng switch (table_flags & ACPI_TABLE_ORIGIN_MASK) { 1428a216d7fSLv Zheng case ACPI_TABLE_ORIGIN_INTERN_PHYSICAL: 1437f9fc99cSLv Zheng 1447f9fc99cSLv Zheng acpi_os_unmap_memory(table, table_length); 1457f9fc99cSLv Zheng break; 1467f9fc99cSLv Zheng 1478a216d7fSLv Zheng case ACPI_TABLE_ORIGIN_INTERN_VIRTUAL: 1488a216d7fSLv Zheng case ACPI_TABLE_ORIGIN_EXTERN_VIRTUAL: 1497f9fc99cSLv Zheng default: 1507f9fc99cSLv Zheng 1517f9fc99cSLv Zheng break; 1527f9fc99cSLv Zheng } 1537f9fc99cSLv Zheng } 1547f9fc99cSLv Zheng 1557f9fc99cSLv Zheng /****************************************************************************** 1567f9fc99cSLv Zheng * 1577f9fc99cSLv Zheng * FUNCTION: acpi_tb_validate_table 1587f9fc99cSLv Zheng * 1597f9fc99cSLv Zheng * PARAMETERS: table_desc - Table descriptor 1607f9fc99cSLv Zheng * 1617f9fc99cSLv Zheng * RETURN: Status 1627f9fc99cSLv Zheng * 16386dfc6f3SLv Zheng * DESCRIPTION: This function is called to validate the table, the returned 16486dfc6f3SLv Zheng * table descriptor is in "VALIDATED" state. 1657f9fc99cSLv Zheng * 1667f9fc99cSLv Zheng *****************************************************************************/ 1677f9fc99cSLv Zheng 1687f9fc99cSLv Zheng acpi_status acpi_tb_validate_table(struct acpi_table_desc *table_desc) 1697f9fc99cSLv Zheng { 1707f9fc99cSLv Zheng acpi_status status = AE_OK; 1717f9fc99cSLv Zheng 1727f9fc99cSLv Zheng ACPI_FUNCTION_TRACE(tb_validate_table); 1737f9fc99cSLv Zheng 1747f9fc99cSLv Zheng /* Validate the table if necessary */ 1757f9fc99cSLv Zheng 17695b482a8SLen Brown if (!table_desc->pointer) { 1777f9fc99cSLv Zheng status = acpi_tb_acquire_table(table_desc, &table_desc->pointer, 1787f9fc99cSLv Zheng &table_desc->length, 1797f9fc99cSLv Zheng &table_desc->flags); 18086dfc6f3SLv Zheng if (!table_desc->pointer) { 18186dfc6f3SLv Zheng status = AE_NO_MEMORY; 18295b482a8SLen Brown } 18395b482a8SLen Brown } 18495b482a8SLen Brown 18595b482a8SLen Brown return_ACPI_STATUS(status); 18695b482a8SLen Brown } 18795b482a8SLen Brown 18895b482a8SLen Brown /******************************************************************************* 18995b482a8SLen Brown * 1907f9fc99cSLv Zheng * FUNCTION: acpi_tb_invalidate_table 1917f9fc99cSLv Zheng * 1927f9fc99cSLv Zheng * PARAMETERS: table_desc - Table descriptor 1937f9fc99cSLv Zheng * 1947f9fc99cSLv Zheng * RETURN: None 1957f9fc99cSLv Zheng * 1967f9fc99cSLv Zheng * DESCRIPTION: Invalidate one internal ACPI table, this is reversal of 1977f9fc99cSLv Zheng * acpi_tb_validate_table(). 1987f9fc99cSLv Zheng * 1997f9fc99cSLv Zheng ******************************************************************************/ 2007f9fc99cSLv Zheng 2017f9fc99cSLv Zheng void acpi_tb_invalidate_table(struct acpi_table_desc *table_desc) 2027f9fc99cSLv Zheng { 2037f9fc99cSLv Zheng 2047f9fc99cSLv Zheng ACPI_FUNCTION_TRACE(tb_invalidate_table); 2057f9fc99cSLv Zheng 2067f9fc99cSLv Zheng /* Table must be validated */ 2077f9fc99cSLv Zheng 2087f9fc99cSLv Zheng if (!table_desc->pointer) { 2097f9fc99cSLv Zheng return_VOID; 2107f9fc99cSLv Zheng } 2117f9fc99cSLv Zheng 2127f9fc99cSLv Zheng acpi_tb_release_table(table_desc->pointer, table_desc->length, 2137f9fc99cSLv Zheng table_desc->flags); 2147f9fc99cSLv Zheng table_desc->pointer = NULL; 2157f9fc99cSLv Zheng 2167f9fc99cSLv Zheng return_VOID; 2177f9fc99cSLv Zheng } 2187f9fc99cSLv Zheng 21986dfc6f3SLv Zheng /****************************************************************************** 2207f9fc99cSLv Zheng * 22186dfc6f3SLv Zheng * FUNCTION: acpi_tb_verify_table 22295b482a8SLen Brown * 22395b482a8SLen Brown * PARAMETERS: table_desc - Table descriptor 22486dfc6f3SLv Zheng * signature - Table signature to verify 22595b482a8SLen Brown * 22695b482a8SLen Brown * RETURN: Status 22795b482a8SLen Brown * 22886dfc6f3SLv Zheng * DESCRIPTION: This function is called to validate and verify the table, the 22986dfc6f3SLv Zheng * returned table descriptor is in "VALIDATED" state. 23086dfc6f3SLv Zheng * 23186dfc6f3SLv Zheng *****************************************************************************/ 23286dfc6f3SLv Zheng 23386dfc6f3SLv Zheng acpi_status 23486dfc6f3SLv Zheng acpi_tb_verify_table(struct acpi_table_desc *table_desc, char *signature) 23586dfc6f3SLv Zheng { 23686dfc6f3SLv Zheng acpi_status status = AE_OK; 23786dfc6f3SLv Zheng 23886dfc6f3SLv Zheng ACPI_FUNCTION_TRACE(tb_verify_table); 23986dfc6f3SLv Zheng 24086dfc6f3SLv Zheng /* Validate the table */ 24186dfc6f3SLv Zheng 24286dfc6f3SLv Zheng status = acpi_tb_validate_table(table_desc); 24386dfc6f3SLv Zheng if (ACPI_FAILURE(status)) { 24486dfc6f3SLv Zheng return_ACPI_STATUS(AE_NO_MEMORY); 24586dfc6f3SLv Zheng } 24686dfc6f3SLv Zheng 24786dfc6f3SLv Zheng /* If a particular signature is expected (DSDT/FACS), it must match */ 24886dfc6f3SLv Zheng 24986dfc6f3SLv Zheng if (signature && !ACPI_COMPARE_NAME(&table_desc->signature, signature)) { 25086dfc6f3SLv Zheng ACPI_BIOS_ERROR((AE_INFO, 25186dfc6f3SLv Zheng "Invalid signature 0x%X for ACPI table, expected [%s]", 25286dfc6f3SLv Zheng table_desc->signature.integer, signature)); 25386dfc6f3SLv Zheng status = AE_BAD_SIGNATURE; 25486dfc6f3SLv Zheng goto invalidate_and_exit; 25586dfc6f3SLv Zheng } 25686dfc6f3SLv Zheng 25786dfc6f3SLv Zheng /* Verify the checksum */ 25886dfc6f3SLv Zheng 25986dfc6f3SLv Zheng status = 26086dfc6f3SLv Zheng acpi_tb_verify_checksum(table_desc->pointer, table_desc->length); 26186dfc6f3SLv Zheng if (ACPI_FAILURE(status)) { 26286dfc6f3SLv Zheng ACPI_EXCEPTION((AE_INFO, AE_NO_MEMORY, 26386dfc6f3SLv Zheng "%4.4s " ACPI_PRINTF_UINT 26486dfc6f3SLv Zheng " Attempted table install failed", 26586dfc6f3SLv Zheng acpi_ut_valid_acpi_name(table_desc->signature. 26686dfc6f3SLv Zheng ascii) ? table_desc-> 26786dfc6f3SLv Zheng signature.ascii : "????", 26886dfc6f3SLv Zheng ACPI_FORMAT_TO_UINT(table_desc->address))); 26986dfc6f3SLv Zheng goto invalidate_and_exit; 27086dfc6f3SLv Zheng } 27186dfc6f3SLv Zheng 27286dfc6f3SLv Zheng return_ACPI_STATUS(AE_OK); 27386dfc6f3SLv Zheng 27486dfc6f3SLv Zheng invalidate_and_exit: 27586dfc6f3SLv Zheng acpi_tb_invalidate_table(table_desc); 27686dfc6f3SLv Zheng return_ACPI_STATUS(status); 27786dfc6f3SLv Zheng } 27886dfc6f3SLv Zheng 27986dfc6f3SLv Zheng /******************************************************************************* 28086dfc6f3SLv Zheng * 28186dfc6f3SLv Zheng * FUNCTION: acpi_tb_install_table 28286dfc6f3SLv Zheng * 28386dfc6f3SLv Zheng * PARAMETERS: table_desc - Table descriptor 28486dfc6f3SLv Zheng * address - Physical address of the table 28586dfc6f3SLv Zheng * flags - Allocation flags of the table 28686dfc6f3SLv Zheng * table - Pointer to the table 28786dfc6f3SLv Zheng * 28886dfc6f3SLv Zheng * RETURN: None 28986dfc6f3SLv Zheng * 29086dfc6f3SLv Zheng * DESCRIPTION: Install an ACPI table into the global data structure. 29186dfc6f3SLv Zheng * 29286dfc6f3SLv Zheng ******************************************************************************/ 29386dfc6f3SLv Zheng 29486dfc6f3SLv Zheng void 29586dfc6f3SLv Zheng acpi_tb_install_table(struct acpi_table_desc *table_desc, 29686dfc6f3SLv Zheng acpi_physical_address address, 29786dfc6f3SLv Zheng u8 flags, struct acpi_table_header *table) 29886dfc6f3SLv Zheng { 29986dfc6f3SLv Zheng /* 30086dfc6f3SLv Zheng * Initialize the table entry. Set the pointer to NULL, since the 30186dfc6f3SLv Zheng * table is not fully mapped at this time. 30286dfc6f3SLv Zheng */ 30386dfc6f3SLv Zheng ACPI_MEMSET(table_desc, 0, sizeof(struct acpi_table_desc)); 30486dfc6f3SLv Zheng table_desc->address = address; 30586dfc6f3SLv Zheng table_desc->length = table->length; 30686dfc6f3SLv Zheng table_desc->flags = flags; 30786dfc6f3SLv Zheng ACPI_MOVE_32_TO_32(table_desc->signature.ascii, table->signature); 30886dfc6f3SLv Zheng } 30986dfc6f3SLv Zheng 31086dfc6f3SLv Zheng /******************************************************************************* 31186dfc6f3SLv Zheng * 31286dfc6f3SLv Zheng * FUNCTION: acpi_tb_acquire_temporal_table 31386dfc6f3SLv Zheng * 31486dfc6f3SLv Zheng * PARAMETERS: table_desc - Table descriptor to be acquired 31586dfc6f3SLv Zheng * address - Address of the table 31686dfc6f3SLv Zheng * flags - Allocation flags of the table 31786dfc6f3SLv Zheng * 31886dfc6f3SLv Zheng * RETURN: Status 31986dfc6f3SLv Zheng * 32086dfc6f3SLv Zheng * DESCRIPTION: This function validates the table header to obtain the length 32186dfc6f3SLv Zheng * of a table and fills the table descriptor to make its state as 32286dfc6f3SLv Zheng * "INSTALLED". Such table descriptor is only used for verified 32386dfc6f3SLv Zheng * installation. 32486dfc6f3SLv Zheng * 32586dfc6f3SLv Zheng ******************************************************************************/ 32686dfc6f3SLv Zheng 32786dfc6f3SLv Zheng static acpi_status 32886dfc6f3SLv Zheng acpi_tb_acquire_temporal_table(struct acpi_table_desc *table_desc, 32986dfc6f3SLv Zheng acpi_physical_address address, u8 flags) 33086dfc6f3SLv Zheng { 33186dfc6f3SLv Zheng struct acpi_table_header *table_header; 33286dfc6f3SLv Zheng 33386dfc6f3SLv Zheng switch (flags & ACPI_TABLE_ORIGIN_MASK) { 3348a216d7fSLv Zheng case ACPI_TABLE_ORIGIN_INTERN_PHYSICAL: 33586dfc6f3SLv Zheng 33686dfc6f3SLv Zheng /* Try to obtain the length of the table */ 33786dfc6f3SLv Zheng 33886dfc6f3SLv Zheng table_header = 33986dfc6f3SLv Zheng acpi_os_map_memory(address, 34086dfc6f3SLv Zheng sizeof(struct acpi_table_header)); 34186dfc6f3SLv Zheng if (!table_header) { 34286dfc6f3SLv Zheng return (AE_NO_MEMORY); 34386dfc6f3SLv Zheng } 34486dfc6f3SLv Zheng acpi_tb_install_table(table_desc, address, flags, table_header); 34586dfc6f3SLv Zheng acpi_os_unmap_memory(table_header, 34686dfc6f3SLv Zheng sizeof(struct acpi_table_header)); 34786dfc6f3SLv Zheng return (AE_OK); 34886dfc6f3SLv Zheng 3498a216d7fSLv Zheng case ACPI_TABLE_ORIGIN_INTERN_VIRTUAL: 3508a216d7fSLv Zheng case ACPI_TABLE_ORIGIN_EXTERN_VIRTUAL: 35186dfc6f3SLv Zheng 35286dfc6f3SLv Zheng table_header = ACPI_CAST_PTR(struct acpi_table_header, address); 35386dfc6f3SLv Zheng if (!table_header) { 35486dfc6f3SLv Zheng return (AE_NO_MEMORY); 35586dfc6f3SLv Zheng } 35686dfc6f3SLv Zheng acpi_tb_install_table(table_desc, address, flags, table_header); 35786dfc6f3SLv Zheng return (AE_OK); 35886dfc6f3SLv Zheng 35986dfc6f3SLv Zheng default: 36086dfc6f3SLv Zheng 36186dfc6f3SLv Zheng break; 36286dfc6f3SLv Zheng } 36386dfc6f3SLv Zheng 36486dfc6f3SLv Zheng /* Table is not valid yet */ 36586dfc6f3SLv Zheng 36686dfc6f3SLv Zheng return (AE_NO_MEMORY); 36786dfc6f3SLv Zheng } 36886dfc6f3SLv Zheng 36986dfc6f3SLv Zheng /******************************************************************************* 37086dfc6f3SLv Zheng * 37186dfc6f3SLv Zheng * FUNCTION: acpi_tb_release_temporal_table 37286dfc6f3SLv Zheng * 37386dfc6f3SLv Zheng * PARAMETERS: table_desc - Table descriptor to be released 37486dfc6f3SLv Zheng * 37586dfc6f3SLv Zheng * RETURN: Status 37686dfc6f3SLv Zheng * 37786dfc6f3SLv Zheng * DESCRIPTION: The reversal of acpi_tb_acquire_temporal_table(). 37886dfc6f3SLv Zheng * 37986dfc6f3SLv Zheng ******************************************************************************/ 38086dfc6f3SLv Zheng 38186dfc6f3SLv Zheng static void acpi_tb_release_temporal_table(struct acpi_table_desc *table_desc) 38286dfc6f3SLv Zheng { 38386dfc6f3SLv Zheng /* 38486dfc6f3SLv Zheng * Note that the .Address is maintained by the callers of 38586dfc6f3SLv Zheng * acpi_tb_acquire_temporal_table(), thus do not invoke acpi_tb_uninstall_table() 38686dfc6f3SLv Zheng * where .Address will be freed. 38786dfc6f3SLv Zheng */ 38886dfc6f3SLv Zheng acpi_tb_invalidate_table(table_desc); 38986dfc6f3SLv Zheng } 39086dfc6f3SLv Zheng 39186dfc6f3SLv Zheng /******************************************************************************* 39286dfc6f3SLv Zheng * 39386dfc6f3SLv Zheng * FUNCTION: acpi_tb_install_and_override_table 39486dfc6f3SLv Zheng * 39586dfc6f3SLv Zheng * PARAMETERS: table_index - Index into root table array 39686dfc6f3SLv Zheng * new_table_desc - New table descriptor to install 39786dfc6f3SLv Zheng * 39886dfc6f3SLv Zheng * RETURN: None 39986dfc6f3SLv Zheng * 40086dfc6f3SLv Zheng * DESCRIPTION: Install an ACPI table into the global data structure. The 40186dfc6f3SLv Zheng * table override mechanism is called to allow the host 40286dfc6f3SLv Zheng * OS to replace any table before it is installed in the root 40386dfc6f3SLv Zheng * table array. 40486dfc6f3SLv Zheng * 40586dfc6f3SLv Zheng ******************************************************************************/ 40686dfc6f3SLv Zheng 40786dfc6f3SLv Zheng void 40886dfc6f3SLv Zheng acpi_tb_install_and_override_table(u32 table_index, 40986dfc6f3SLv Zheng struct acpi_table_desc *new_table_desc) 41086dfc6f3SLv Zheng { 41186dfc6f3SLv Zheng if (table_index >= acpi_gbl_root_table_list.current_table_count) { 41286dfc6f3SLv Zheng return; 41386dfc6f3SLv Zheng } 41486dfc6f3SLv Zheng 41586dfc6f3SLv Zheng /* 41686dfc6f3SLv Zheng * ACPI Table Override: 41786dfc6f3SLv Zheng * 41886dfc6f3SLv Zheng * Before we install the table, let the host OS override it with a new 41986dfc6f3SLv Zheng * one if desired. Any table within the RSDT/XSDT can be replaced, 42086dfc6f3SLv Zheng * including the DSDT which is pointed to by the FADT. 42186dfc6f3SLv Zheng */ 42286dfc6f3SLv Zheng acpi_tb_override_table(new_table_desc); 42386dfc6f3SLv Zheng 42486dfc6f3SLv Zheng acpi_tb_install_table(&acpi_gbl_root_table_list.tables[table_index], 42586dfc6f3SLv Zheng new_table_desc->address, new_table_desc->flags, 42686dfc6f3SLv Zheng new_table_desc->pointer); 42786dfc6f3SLv Zheng 42886dfc6f3SLv Zheng acpi_tb_print_table_header(new_table_desc->address, 42986dfc6f3SLv Zheng new_table_desc->pointer); 43086dfc6f3SLv Zheng 43186dfc6f3SLv Zheng /* Set the global integer width (based upon revision of the DSDT) */ 43286dfc6f3SLv Zheng 43386dfc6f3SLv Zheng if (table_index == ACPI_TABLE_INDEX_DSDT) { 43486dfc6f3SLv Zheng acpi_ut_set_integer_width(new_table_desc->pointer->revision); 43586dfc6f3SLv Zheng } 43686dfc6f3SLv Zheng } 43786dfc6f3SLv Zheng 43886dfc6f3SLv Zheng /******************************************************************************* 43986dfc6f3SLv Zheng * 44086dfc6f3SLv Zheng * FUNCTION: acpi_tb_install_fixed_table 44186dfc6f3SLv Zheng * 44286dfc6f3SLv Zheng * PARAMETERS: address - Physical address of DSDT or FACS 44386dfc6f3SLv Zheng * signature - Table signature, NULL if no need to 44486dfc6f3SLv Zheng * match 44586dfc6f3SLv Zheng * table_index - Index into root table array 44686dfc6f3SLv Zheng * 44786dfc6f3SLv Zheng * RETURN: Status 44886dfc6f3SLv Zheng * 44986dfc6f3SLv Zheng * DESCRIPTION: Install a fixed ACPI table (DSDT/FACS) into the global data 45086dfc6f3SLv Zheng * structure. 45195b482a8SLen Brown * 45295b482a8SLen Brown ******************************************************************************/ 45395b482a8SLen Brown 45495b482a8SLen Brown acpi_status 45586dfc6f3SLv Zheng acpi_tb_install_fixed_table(acpi_physical_address address, 45686dfc6f3SLv Zheng char *signature, u32 table_index) 45786dfc6f3SLv Zheng { 45886dfc6f3SLv Zheng struct acpi_table_desc new_table_desc; 45986dfc6f3SLv Zheng acpi_status status; 46086dfc6f3SLv Zheng 46186dfc6f3SLv Zheng ACPI_FUNCTION_TRACE(tb_install_fixed_table); 46286dfc6f3SLv Zheng 46386dfc6f3SLv Zheng if (!address) { 46486dfc6f3SLv Zheng ACPI_ERROR((AE_INFO, 46586dfc6f3SLv Zheng "Null physical address for ACPI table [%s]", 46686dfc6f3SLv Zheng signature)); 46786dfc6f3SLv Zheng return (AE_NO_MEMORY); 46886dfc6f3SLv Zheng } 46986dfc6f3SLv Zheng 47086dfc6f3SLv Zheng /* Fill a table descriptor for validation */ 47186dfc6f3SLv Zheng 47286dfc6f3SLv Zheng status = acpi_tb_acquire_temporal_table(&new_table_desc, address, 4738a216d7fSLv Zheng ACPI_TABLE_ORIGIN_INTERN_PHYSICAL); 47486dfc6f3SLv Zheng if (ACPI_FAILURE(status)) { 47586dfc6f3SLv Zheng ACPI_ERROR((AE_INFO, "Could not acquire table length at %p", 47686dfc6f3SLv Zheng ACPI_CAST_PTR(void, address))); 47786dfc6f3SLv Zheng return_ACPI_STATUS(status); 47886dfc6f3SLv Zheng } 47986dfc6f3SLv Zheng 48086dfc6f3SLv Zheng /* Validate and verify a table before installation */ 48186dfc6f3SLv Zheng 48286dfc6f3SLv Zheng status = acpi_tb_verify_table(&new_table_desc, signature); 48386dfc6f3SLv Zheng if (ACPI_FAILURE(status)) { 48486dfc6f3SLv Zheng goto release_and_exit; 48586dfc6f3SLv Zheng } 48686dfc6f3SLv Zheng 48786dfc6f3SLv Zheng acpi_tb_install_and_override_table(table_index, &new_table_desc); 48886dfc6f3SLv Zheng 48986dfc6f3SLv Zheng release_and_exit: 49086dfc6f3SLv Zheng 49186dfc6f3SLv Zheng /* Release the temporal table descriptor */ 49286dfc6f3SLv Zheng 49386dfc6f3SLv Zheng acpi_tb_release_temporal_table(&new_table_desc); 49486dfc6f3SLv Zheng return_ACPI_STATUS(status); 49586dfc6f3SLv Zheng } 49686dfc6f3SLv Zheng 49786dfc6f3SLv Zheng /******************************************************************************* 49886dfc6f3SLv Zheng * 49986dfc6f3SLv Zheng * FUNCTION: acpi_tb_is_equivalent_table 50086dfc6f3SLv Zheng * 50186dfc6f3SLv Zheng * PARAMETERS: table_desc - Table 1 descriptor to be compared 50286dfc6f3SLv Zheng * table_index - Index of table 2 to be compared 50386dfc6f3SLv Zheng * 50486dfc6f3SLv Zheng * RETURN: TRUE if 2 tables are equivalent 50586dfc6f3SLv Zheng * 50686dfc6f3SLv Zheng * DESCRIPTION: This function is called to compare a table with what have 50786dfc6f3SLv Zheng * already been installed in the root table list. 50886dfc6f3SLv Zheng * 50986dfc6f3SLv Zheng ******************************************************************************/ 51086dfc6f3SLv Zheng 51186dfc6f3SLv Zheng static u8 51286dfc6f3SLv Zheng acpi_tb_is_equivalent_table(struct acpi_table_desc *table_desc, u32 table_index) 51386dfc6f3SLv Zheng { 51486dfc6f3SLv Zheng acpi_status status = AE_OK; 51586dfc6f3SLv Zheng u8 is_equivalent; 51686dfc6f3SLv Zheng struct acpi_table_header *table; 51786dfc6f3SLv Zheng u32 table_length; 51886dfc6f3SLv Zheng u8 table_flags; 51986dfc6f3SLv Zheng 52086dfc6f3SLv Zheng status = 52186dfc6f3SLv Zheng acpi_tb_acquire_table(&acpi_gbl_root_table_list.tables[table_index], 52286dfc6f3SLv Zheng &table, &table_length, &table_flags); 52386dfc6f3SLv Zheng if (ACPI_FAILURE(status)) { 52486dfc6f3SLv Zheng return (FALSE); 52586dfc6f3SLv Zheng } 52686dfc6f3SLv Zheng 52786dfc6f3SLv Zheng /* 52886dfc6f3SLv Zheng * Check for a table match on the entire table length, 52986dfc6f3SLv Zheng * not just the header. 53086dfc6f3SLv Zheng */ 53186dfc6f3SLv Zheng is_equivalent = (u8)((table_desc->length != table_length || 53286dfc6f3SLv Zheng ACPI_MEMCMP(table_desc->pointer, table, 53386dfc6f3SLv Zheng table_length)) ? FALSE : TRUE); 53486dfc6f3SLv Zheng 53586dfc6f3SLv Zheng /* Release the acquired table */ 53686dfc6f3SLv Zheng 53786dfc6f3SLv Zheng acpi_tb_release_table(table, table_length, table_flags); 53886dfc6f3SLv Zheng 53986dfc6f3SLv Zheng return (is_equivalent); 54086dfc6f3SLv Zheng } 54186dfc6f3SLv Zheng 54286dfc6f3SLv Zheng /******************************************************************************* 54386dfc6f3SLv Zheng * 54486dfc6f3SLv Zheng * FUNCTION: acpi_tb_install_non_fixed_table 54586dfc6f3SLv Zheng * 5468a216d7fSLv Zheng * PARAMETERS: address - Address of the table (might be a virtual 54786dfc6f3SLv Zheng * address depending on the table_flags) 54886dfc6f3SLv Zheng * flags - Flags for the table 54986dfc6f3SLv Zheng * reload - Whether reload should be performed 55086dfc6f3SLv Zheng * table_index - Where the table index is returned 55186dfc6f3SLv Zheng * 55286dfc6f3SLv Zheng * RETURN: Status 55386dfc6f3SLv Zheng * 55486dfc6f3SLv Zheng * DESCRIPTION: This function is called to install an ACPI table that is 55586dfc6f3SLv Zheng * neither DSDT nor FACS. 55686dfc6f3SLv Zheng * When this function is called by "Load" or "LoadTable" opcodes, 55786dfc6f3SLv Zheng * or by acpi_load_table() API, the "Reload" parameter is set. 55886dfc6f3SLv Zheng * After sucessfully returning from this function, table is 55986dfc6f3SLv Zheng * "INSTALLED" but not "VALIDATED". 56086dfc6f3SLv Zheng * 56186dfc6f3SLv Zheng ******************************************************************************/ 56286dfc6f3SLv Zheng 56386dfc6f3SLv Zheng acpi_status 56486dfc6f3SLv Zheng acpi_tb_install_non_fixed_table(acpi_physical_address address, 56586dfc6f3SLv Zheng u8 flags, u8 reload, u32 *table_index) 56695b482a8SLen Brown { 56795b482a8SLen Brown u32 i; 56895b482a8SLen Brown acpi_status status = AE_OK; 56986dfc6f3SLv Zheng struct acpi_table_desc new_table_desc; 57095b482a8SLen Brown 57186dfc6f3SLv Zheng ACPI_FUNCTION_TRACE(tb_install_non_fixed_table); 57295b482a8SLen Brown 57386dfc6f3SLv Zheng /* Acquire a temporal table descriptor for validation */ 57486dfc6f3SLv Zheng 57586dfc6f3SLv Zheng status = 57686dfc6f3SLv Zheng acpi_tb_acquire_temporal_table(&new_table_desc, address, flags); 57786dfc6f3SLv Zheng if (ACPI_FAILURE(status)) { 57886dfc6f3SLv Zheng ACPI_ERROR((AE_INFO, "Could not acquire table length at %p", 57986dfc6f3SLv Zheng ACPI_CAST_PTR(void, address))); 58095b482a8SLen Brown return_ACPI_STATUS(status); 58195b482a8SLen Brown } 58286dfc6f3SLv Zheng 583*a94e88cdSLv Zheng /* 584*a94e88cdSLv Zheng * Optionally do not load any SSDTs from the RSDT/XSDT. This can 585*a94e88cdSLv Zheng * be useful for debugging ACPI problems on some machines. 586*a94e88cdSLv Zheng */ 587*a94e88cdSLv Zheng if (!reload && acpi_gbl_disable_ssdt_table_install && 588*a94e88cdSLv Zheng ACPI_COMPARE_NAME(&new_table_desc.signature, ACPI_SIG_SSDT)) { 589*a94e88cdSLv Zheng ACPI_INFO((AE_INFO, "Ignoring installation of %4.4s at %p", 590*a94e88cdSLv Zheng new_table_desc.signature.ascii, ACPI_CAST_PTR(void, 591*a94e88cdSLv Zheng address))); 592*a94e88cdSLv Zheng goto release_and_exit; 593*a94e88cdSLv Zheng } 594*a94e88cdSLv Zheng 59586dfc6f3SLv Zheng /* Validate and verify a table before installation */ 59686dfc6f3SLv Zheng 59786dfc6f3SLv Zheng status = acpi_tb_verify_table(&new_table_desc, NULL); 59886dfc6f3SLv Zheng if (ACPI_FAILURE(status)) { 59986dfc6f3SLv Zheng goto release_and_exit; 60095b482a8SLen Brown } 60195b482a8SLen Brown 60286dfc6f3SLv Zheng if (reload) { 60395b482a8SLen Brown /* 604c8cefe30SBob Moore * Validate the incoming table signature. 605c8cefe30SBob Moore * 606c8cefe30SBob Moore * 1) Originally, we checked the table signature for "SSDT" or "PSDT". 607c8cefe30SBob Moore * 2) We added support for OEMx tables, signature "OEM". 608c8cefe30SBob Moore * 3) Valid tables were encountered with a null signature, so we just 609c8cefe30SBob Moore * gave up on validating the signature, (05/2008). 610c8cefe30SBob Moore * 4) We encountered non-AML tables such as the MADT, which caused 611c8cefe30SBob Moore * interpreter errors and kernel faults. So now, we once again allow 612c8cefe30SBob Moore * only "SSDT", "OEMx", and now, also a null signature. (05/2011). 61395b482a8SLen Brown */ 61486dfc6f3SLv Zheng if ((new_table_desc.signature.ascii[0] != 0x00) && 61586dfc6f3SLv Zheng (!ACPI_COMPARE_NAME 61686dfc6f3SLv Zheng (&new_table_desc.signature, ACPI_SIG_SSDT)) 61786dfc6f3SLv Zheng && (ACPI_STRNCMP(new_table_desc.signature.ascii, "OEM", 3))) 61886dfc6f3SLv Zheng { 6193b3ea775SBob Moore ACPI_BIOS_ERROR((AE_INFO, 6203b3ea775SBob Moore "Table has invalid signature [%4.4s] (0x%8.8X), " 6213b3ea775SBob Moore "must be SSDT or OEMx", 62286dfc6f3SLv Zheng acpi_ut_valid_acpi_name(new_table_desc. 62386dfc6f3SLv Zheng signature. 62486dfc6f3SLv Zheng ascii) ? 62586dfc6f3SLv Zheng new_table_desc.signature. 62686dfc6f3SLv Zheng ascii : "????", 62786dfc6f3SLv Zheng new_table_desc.signature.integer)); 628c8cefe30SBob Moore 62986dfc6f3SLv Zheng status = AE_BAD_SIGNATURE; 63086dfc6f3SLv Zheng goto release_and_exit; 631c8cefe30SBob Moore } 63295b482a8SLen Brown 63395b482a8SLen Brown /* Check if table is already registered */ 63495b482a8SLen Brown 63586dfc6f3SLv Zheng for (i = 0; i < acpi_gbl_root_table_list.current_table_count; 63686dfc6f3SLv Zheng ++i) { 63795b482a8SLen Brown /* 63895b482a8SLen Brown * Check for a table match on the entire table length, 63995b482a8SLen Brown * not just the header. 64095b482a8SLen Brown */ 64186dfc6f3SLv Zheng if (!acpi_tb_is_equivalent_table(&new_table_desc, i)) { 64295b482a8SLen Brown continue; 64395b482a8SLen Brown } 64495b482a8SLen Brown 64595b482a8SLen Brown /* 64695b482a8SLen Brown * Note: the current mechanism does not unregister a table if it is 64795b482a8SLen Brown * dynamically unloaded. The related namespace entries are deleted, 64895b482a8SLen Brown * but the table remains in the root table list. 64995b482a8SLen Brown * 65095b482a8SLen Brown * The assumption here is that the number of different tables that 65195b482a8SLen Brown * will be loaded is actually small, and there is minimal overhead 65295b482a8SLen Brown * in just keeping the table in case it is needed again. 65395b482a8SLen Brown * 65495b482a8SLen Brown * If this assumption changes in the future (perhaps on large 65595b482a8SLen Brown * machines with many table load/unload operations), tables will 65695b482a8SLen Brown * need to be unregistered when they are unloaded, and slots in the 65795b482a8SLen Brown * root table list should be reused when empty. 65895b482a8SLen Brown */ 65995b482a8SLen Brown if (acpi_gbl_root_table_list.tables[i]. 66095b482a8SLen Brown flags & ACPI_TABLE_IS_LOADED) { 66195b482a8SLen Brown 66295b482a8SLen Brown /* Table is still loaded, this is an error */ 66395b482a8SLen Brown 66495b482a8SLen Brown status = AE_ALREADY_EXISTS; 66586dfc6f3SLv Zheng goto release_and_exit; 66695b482a8SLen Brown } else { 667d3ccaff8SBob Moore /* 66886dfc6f3SLv Zheng * Table was unloaded, allow it to be reloaded. 66986dfc6f3SLv Zheng * As we are going to return AE_OK to the caller, we should 67086dfc6f3SLv Zheng * take the responsibility of freeing the input descriptor. 67186dfc6f3SLv Zheng * Refill the input descriptor to ensure 67286dfc6f3SLv Zheng * acpi_tb_install_and_override_table() can be called again to 67386dfc6f3SLv Zheng * indicate the re-installation. 674d3ccaff8SBob Moore */ 67586dfc6f3SLv Zheng acpi_tb_uninstall_table(&new_table_desc); 67686dfc6f3SLv Zheng *table_index = i; 67786dfc6f3SLv Zheng (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); 67886dfc6f3SLv Zheng return_ACPI_STATUS(AE_OK); 67986dfc6f3SLv Zheng } 68086dfc6f3SLv Zheng } 6817f9fc99cSLv Zheng } 682d3ccaff8SBob Moore 68395b482a8SLen Brown /* Add the table to the global root table list */ 68495b482a8SLen Brown 68586dfc6f3SLv Zheng status = acpi_tb_acquire_root_table_entry(&i); 68695b482a8SLen Brown if (ACPI_FAILURE(status)) { 68786dfc6f3SLv Zheng goto release_and_exit; 68895b482a8SLen Brown } 68986dfc6f3SLv Zheng *table_index = i; 69086dfc6f3SLv Zheng acpi_tb_install_and_override_table(i, &new_table_desc); 69195b482a8SLen Brown 69286dfc6f3SLv Zheng release_and_exit: 69395b482a8SLen Brown 69486dfc6f3SLv Zheng /* Release the temporal table descriptor */ 69586dfc6f3SLv Zheng 69686dfc6f3SLv Zheng acpi_tb_release_temporal_table(&new_table_desc); 69795b482a8SLen Brown return_ACPI_STATUS(status); 69895b482a8SLen Brown } 69995b482a8SLen Brown 70095b482a8SLen Brown /******************************************************************************* 70195b482a8SLen Brown * 7027f9fc99cSLv Zheng * FUNCTION: acpi_tb_override_table 703f7b004a1SBob Moore * 70486dfc6f3SLv Zheng * PARAMETERS: old_table_desc - Validated table descriptor to be 70586dfc6f3SLv Zheng * overridden 706f7b004a1SBob Moore * 70786dfc6f3SLv Zheng * RETURN: None 708f7b004a1SBob Moore * 709f7b004a1SBob Moore * DESCRIPTION: Attempt table override by calling the OSL override functions. 710f7b004a1SBob Moore * Note: If the table is overridden, then the entire new table 7117f9fc99cSLv Zheng * is acquired and returned by this function. 71286dfc6f3SLv Zheng * Before/after invocation, the table descriptor is in a state 71386dfc6f3SLv Zheng * that is "VALIDATED". 714f7b004a1SBob Moore * 715f7b004a1SBob Moore ******************************************************************************/ 716f7b004a1SBob Moore 71786dfc6f3SLv Zheng void acpi_tb_override_table(struct acpi_table_desc *old_table_desc) 718f7b004a1SBob Moore { 719f7b004a1SBob Moore acpi_status status; 720f7b004a1SBob Moore char *override_type; 7217f9fc99cSLv Zheng struct acpi_table_desc new_table_desc; 72286dfc6f3SLv Zheng struct acpi_table_header *table; 72386dfc6f3SLv Zheng acpi_physical_address address; 72486dfc6f3SLv Zheng u32 length; 725f7b004a1SBob Moore 726f7b004a1SBob Moore /* (1) Attempt logical override (returns a logical address) */ 727f7b004a1SBob Moore 72886dfc6f3SLv Zheng status = acpi_os_table_override(old_table_desc->pointer, &table); 72986dfc6f3SLv Zheng if (ACPI_SUCCESS(status) && table) { 73086dfc6f3SLv Zheng acpi_tb_acquire_temporal_table(&new_table_desc, 73186dfc6f3SLv Zheng ACPI_PTR_TO_PHYSADDR(table), 7328a216d7fSLv Zheng ACPI_TABLE_ORIGIN_EXTERN_VIRTUAL); 733f7b004a1SBob Moore override_type = "Logical"; 734f7b004a1SBob Moore goto finish_override; 735f7b004a1SBob Moore } 736f7b004a1SBob Moore 737f7b004a1SBob Moore /* (2) Attempt physical override (returns a physical address) */ 738f7b004a1SBob Moore 73986dfc6f3SLv Zheng status = acpi_os_physical_table_override(old_table_desc->pointer, 74086dfc6f3SLv Zheng &address, &length); 74186dfc6f3SLv Zheng if (ACPI_SUCCESS(status) && address && length) { 74286dfc6f3SLv Zheng acpi_tb_acquire_temporal_table(&new_table_desc, address, 7438a216d7fSLv Zheng ACPI_TABLE_ORIGIN_INTERN_PHYSICAL); 744f7b004a1SBob Moore override_type = "Physical"; 745f7b004a1SBob Moore goto finish_override; 746f7b004a1SBob Moore } 747f7b004a1SBob Moore 74886dfc6f3SLv Zheng return; /* There was no override */ 749f7b004a1SBob Moore 750f7b004a1SBob Moore finish_override: 751f7b004a1SBob Moore 75286dfc6f3SLv Zheng /* Validate and verify a table before overriding */ 75386dfc6f3SLv Zheng 75486dfc6f3SLv Zheng status = acpi_tb_verify_table(&new_table_desc, NULL); 7557f9fc99cSLv Zheng if (ACPI_FAILURE(status)) { 75686dfc6f3SLv Zheng return; 7577f9fc99cSLv Zheng } 7587f9fc99cSLv Zheng 7592e19f8d0SBob Moore ACPI_INFO((AE_INFO, "%4.4s " ACPI_PRINTF_UINT 7602e19f8d0SBob Moore " %s table override, new table: " ACPI_PRINTF_UINT, 76186dfc6f3SLv Zheng old_table_desc->signature.ascii, 76286dfc6f3SLv Zheng ACPI_FORMAT_TO_UINT(old_table_desc->address), 7637f9fc99cSLv Zheng override_type, ACPI_FORMAT_TO_UINT(new_table_desc.address))); 764f7b004a1SBob Moore 76586dfc6f3SLv Zheng /* We can now uninstall the original table */ 766f7b004a1SBob Moore 76786dfc6f3SLv Zheng acpi_tb_uninstall_table(old_table_desc); 768f7b004a1SBob Moore 76986dfc6f3SLv Zheng /* 77086dfc6f3SLv Zheng * Replace the original table descriptor and keep its state as 77186dfc6f3SLv Zheng * "VALIDATED". 77286dfc6f3SLv Zheng */ 77386dfc6f3SLv Zheng acpi_tb_install_table(old_table_desc, new_table_desc.address, 77486dfc6f3SLv Zheng new_table_desc.flags, new_table_desc.pointer); 77586dfc6f3SLv Zheng acpi_tb_validate_table(old_table_desc); 776f7b004a1SBob Moore 77786dfc6f3SLv Zheng /* Release the temporal table descriptor */ 778f7b004a1SBob Moore 77986dfc6f3SLv Zheng acpi_tb_release_temporal_table(&new_table_desc); 780f7b004a1SBob Moore } 781f7b004a1SBob Moore 782f7b004a1SBob Moore /******************************************************************************* 783f7b004a1SBob Moore * 78495b482a8SLen Brown * FUNCTION: acpi_tb_resize_root_table_list 78595b482a8SLen Brown * 78695b482a8SLen Brown * PARAMETERS: None 78795b482a8SLen Brown * 78895b482a8SLen Brown * RETURN: Status 78995b482a8SLen Brown * 79095b482a8SLen Brown * DESCRIPTION: Expand the size of global table array 79195b482a8SLen Brown * 79295b482a8SLen Brown ******************************************************************************/ 79395b482a8SLen Brown 79495b482a8SLen Brown acpi_status acpi_tb_resize_root_table_list(void) 79595b482a8SLen Brown { 79695b482a8SLen Brown struct acpi_table_desc *tables; 7972bc198c1SLv Zheng u32 table_count; 79895b482a8SLen Brown 79995b482a8SLen Brown ACPI_FUNCTION_TRACE(tb_resize_root_table_list); 80095b482a8SLen Brown 80195b482a8SLen Brown /* allow_resize flag is a parameter to acpi_initialize_tables */ 80295b482a8SLen Brown 80395b482a8SLen Brown if (!(acpi_gbl_root_table_list.flags & ACPI_ROOT_ALLOW_RESIZE)) { 80495b482a8SLen Brown ACPI_ERROR((AE_INFO, 80595b482a8SLen Brown "Resize of Root Table Array is not allowed")); 80695b482a8SLen Brown return_ACPI_STATUS(AE_SUPPORT); 80795b482a8SLen Brown } 80895b482a8SLen Brown 80995b482a8SLen Brown /* Increase the Table Array size */ 81095b482a8SLen Brown 8112bc198c1SLv Zheng if (acpi_gbl_root_table_list.flags & ACPI_ROOT_ORIGIN_ALLOCATED) { 8122bc198c1SLv Zheng table_count = acpi_gbl_root_table_list.max_table_count; 8132bc198c1SLv Zheng } else { 8142bc198c1SLv Zheng table_count = acpi_gbl_root_table_list.current_table_count; 8152bc198c1SLv Zheng } 8162bc198c1SLv Zheng 8172bc198c1SLv Zheng tables = ACPI_ALLOCATE_ZEROED(((acpi_size) table_count + 818ec41f193SBob Moore ACPI_ROOT_TABLE_SIZE_INCREMENT) * 819ec41f193SBob Moore sizeof(struct acpi_table_desc)); 82095b482a8SLen Brown if (!tables) { 82195b482a8SLen Brown ACPI_ERROR((AE_INFO, 82295b482a8SLen Brown "Could not allocate new root table array")); 82395b482a8SLen Brown return_ACPI_STATUS(AE_NO_MEMORY); 82495b482a8SLen Brown } 82595b482a8SLen Brown 82695b482a8SLen Brown /* Copy and free the previous table array */ 82795b482a8SLen Brown 82895b482a8SLen Brown if (acpi_gbl_root_table_list.tables) { 82995b482a8SLen Brown ACPI_MEMCPY(tables, acpi_gbl_root_table_list.tables, 8302bc198c1SLv Zheng (acpi_size) table_count * 8312bc198c1SLv Zheng sizeof(struct acpi_table_desc)); 83295b482a8SLen Brown 83395b482a8SLen Brown if (acpi_gbl_root_table_list.flags & ACPI_ROOT_ORIGIN_ALLOCATED) { 83495b482a8SLen Brown ACPI_FREE(acpi_gbl_root_table_list.tables); 83595b482a8SLen Brown } 83695b482a8SLen Brown } 83795b482a8SLen Brown 83895b482a8SLen Brown acpi_gbl_root_table_list.tables = tables; 8392bc198c1SLv Zheng acpi_gbl_root_table_list.max_table_count = 8402bc198c1SLv Zheng table_count + ACPI_ROOT_TABLE_SIZE_INCREMENT; 8412bc198c1SLv Zheng acpi_gbl_root_table_list.flags |= ACPI_ROOT_ORIGIN_ALLOCATED; 84295b482a8SLen Brown 84395b482a8SLen Brown return_ACPI_STATUS(AE_OK); 84495b482a8SLen Brown } 84595b482a8SLen Brown 84695b482a8SLen Brown /******************************************************************************* 84795b482a8SLen Brown * 84886dfc6f3SLv Zheng * FUNCTION: acpi_tb_acquire_root_table_entry 84986dfc6f3SLv Zheng * 85086dfc6f3SLv Zheng * PARAMETERS: table_index - Where table index is returned 85186dfc6f3SLv Zheng * 85286dfc6f3SLv Zheng * RETURN: Status and table index. 85386dfc6f3SLv Zheng * 85486dfc6f3SLv Zheng * DESCRIPTION: Allocate a new ACPI table entry to the global table list 85586dfc6f3SLv Zheng * 85686dfc6f3SLv Zheng ******************************************************************************/ 85786dfc6f3SLv Zheng 85886dfc6f3SLv Zheng static acpi_status acpi_tb_acquire_root_table_entry(u32 *table_index) 85986dfc6f3SLv Zheng { 86086dfc6f3SLv Zheng acpi_status status; 86186dfc6f3SLv Zheng 86286dfc6f3SLv Zheng /* Ensure that there is room for the table in the Root Table List */ 86386dfc6f3SLv Zheng 86486dfc6f3SLv Zheng if (acpi_gbl_root_table_list.current_table_count >= 86586dfc6f3SLv Zheng acpi_gbl_root_table_list.max_table_count) { 86686dfc6f3SLv Zheng status = acpi_tb_resize_root_table_list(); 86786dfc6f3SLv Zheng if (ACPI_FAILURE(status)) { 86886dfc6f3SLv Zheng return (status); 86986dfc6f3SLv Zheng } 87086dfc6f3SLv Zheng } 87186dfc6f3SLv Zheng 87286dfc6f3SLv Zheng *table_index = acpi_gbl_root_table_list.current_table_count; 87386dfc6f3SLv Zheng acpi_gbl_root_table_list.current_table_count++; 87486dfc6f3SLv Zheng return (AE_OK); 87586dfc6f3SLv Zheng } 87686dfc6f3SLv Zheng 87786dfc6f3SLv Zheng /******************************************************************************* 87886dfc6f3SLv Zheng * 87995b482a8SLen Brown * FUNCTION: acpi_tb_store_table 88095b482a8SLen Brown * 881ba494beeSBob Moore * PARAMETERS: address - Table address 882ba494beeSBob Moore * table - Table header 883ba494beeSBob Moore * length - Table length 884ba494beeSBob Moore * flags - flags 88595b482a8SLen Brown * 88695b482a8SLen Brown * RETURN: Status and table index. 88795b482a8SLen Brown * 88895b482a8SLen Brown * DESCRIPTION: Add an ACPI table to the global table list 88995b482a8SLen Brown * 89095b482a8SLen Brown ******************************************************************************/ 89195b482a8SLen Brown 89295b482a8SLen Brown acpi_status 89395b482a8SLen Brown acpi_tb_store_table(acpi_physical_address address, 89495b482a8SLen Brown struct acpi_table_header * table, 89595b482a8SLen Brown u32 length, u8 flags, u32 *table_index) 89695b482a8SLen Brown { 897b9ee2043SBob Moore acpi_status status; 89886dfc6f3SLv Zheng struct acpi_table_desc *table_desc; 89995b482a8SLen Brown 90086dfc6f3SLv Zheng status = acpi_tb_acquire_root_table_entry(table_index); 90195b482a8SLen Brown if (ACPI_FAILURE(status)) { 90295b482a8SLen Brown return (status); 90395b482a8SLen Brown } 904b9ee2043SBob Moore 90595b482a8SLen Brown /* Initialize added table */ 90695b482a8SLen Brown 90786dfc6f3SLv Zheng table_desc = &acpi_gbl_root_table_list.tables[*table_index]; 90886dfc6f3SLv Zheng acpi_tb_install_table(table_desc, address, flags, table); 90986dfc6f3SLv Zheng table_desc->pointer = table; 91095b482a8SLen Brown 911b9ee2043SBob Moore return (AE_OK); 91295b482a8SLen Brown } 91395b482a8SLen Brown 91495b482a8SLen Brown /******************************************************************************* 91595b482a8SLen Brown * 9167f9fc99cSLv Zheng * FUNCTION: acpi_tb_uninstall_table 91795b482a8SLen Brown * 9187f9fc99cSLv Zheng * PARAMETERS: table_desc - Table descriptor 91995b482a8SLen Brown * 92095b482a8SLen Brown * RETURN: None 92195b482a8SLen Brown * 92295b482a8SLen Brown * DESCRIPTION: Delete one internal ACPI table 92395b482a8SLen Brown * 92495b482a8SLen Brown ******************************************************************************/ 92595b482a8SLen Brown 9267f9fc99cSLv Zheng void acpi_tb_uninstall_table(struct acpi_table_desc *table_desc) 92795b482a8SLen Brown { 9285582982dSLv Zheng 9297f9fc99cSLv Zheng ACPI_FUNCTION_TRACE(tb_uninstall_table); 9305582982dSLv Zheng 9317f9fc99cSLv Zheng /* Table must be installed */ 9327f9fc99cSLv Zheng 9337f9fc99cSLv Zheng if (!table_desc->address) { 9347f9fc99cSLv Zheng return_VOID; 93595b482a8SLen Brown } 9365582982dSLv Zheng 9377f9fc99cSLv Zheng acpi_tb_invalidate_table(table_desc); 9381d1ea1b7SChao Guan 9397f9fc99cSLv Zheng if ((table_desc->flags & ACPI_TABLE_ORIGIN_MASK) == 9408a216d7fSLv Zheng ACPI_TABLE_ORIGIN_INTERN_VIRTUAL) { 9417f9fc99cSLv Zheng ACPI_FREE(ACPI_CAST_PTR(void, table_desc->address)); 9427f9fc99cSLv Zheng } 9431d1ea1b7SChao Guan 944dc156adfSLv Zheng table_desc->address = ACPI_PTR_TO_PHYSADDR(NULL); 945f7b004a1SBob Moore 9467f9fc99cSLv Zheng return_VOID; 94795b482a8SLen Brown } 94895b482a8SLen Brown 94995b482a8SLen Brown /******************************************************************************* 95095b482a8SLen Brown * 95195b482a8SLen Brown * FUNCTION: acpi_tb_terminate 95295b482a8SLen Brown * 95395b482a8SLen Brown * PARAMETERS: None 95495b482a8SLen Brown * 95595b482a8SLen Brown * RETURN: None 95695b482a8SLen Brown * 95795b482a8SLen Brown * DESCRIPTION: Delete all internal ACPI tables 95895b482a8SLen Brown * 95995b482a8SLen Brown ******************************************************************************/ 96095b482a8SLen Brown 96195b482a8SLen Brown void acpi_tb_terminate(void) 96295b482a8SLen Brown { 96395b482a8SLen Brown u32 i; 96495b482a8SLen Brown 96595b482a8SLen Brown ACPI_FUNCTION_TRACE(tb_terminate); 96695b482a8SLen Brown 96795b482a8SLen Brown (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); 96895b482a8SLen Brown 96995b482a8SLen Brown /* Delete the individual tables */ 97095b482a8SLen Brown 971b9ee2043SBob Moore for (i = 0; i < acpi_gbl_root_table_list.current_table_count; i++) { 9727f9fc99cSLv Zheng acpi_tb_uninstall_table(&acpi_gbl_root_table_list.tables[i]); 97395b482a8SLen Brown } 97495b482a8SLen Brown 97595b482a8SLen Brown /* 97695b482a8SLen Brown * Delete the root table array if allocated locally. Array cannot be 97795b482a8SLen Brown * mapped, so we don't need to check for that flag. 97895b482a8SLen Brown */ 97995b482a8SLen Brown if (acpi_gbl_root_table_list.flags & ACPI_ROOT_ORIGIN_ALLOCATED) { 98095b482a8SLen Brown ACPI_FREE(acpi_gbl_root_table_list.tables); 98195b482a8SLen Brown } 98295b482a8SLen Brown 98395b482a8SLen Brown acpi_gbl_root_table_list.tables = NULL; 98495b482a8SLen Brown acpi_gbl_root_table_list.flags = 0; 985b9ee2043SBob Moore acpi_gbl_root_table_list.current_table_count = 0; 98695b482a8SLen Brown 98795b482a8SLen Brown ACPI_DEBUG_PRINT((ACPI_DB_INFO, "ACPI Tables freed\n")); 98895b482a8SLen Brown (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); 98968aafc35SBob Moore 99068aafc35SBob Moore return_VOID; 99195b482a8SLen Brown } 99295b482a8SLen Brown 99395b482a8SLen Brown /******************************************************************************* 99495b482a8SLen Brown * 99595b482a8SLen Brown * FUNCTION: acpi_tb_delete_namespace_by_owner 99695b482a8SLen Brown * 99795b482a8SLen Brown * PARAMETERS: table_index - Table index 99895b482a8SLen Brown * 9998a335a23SBob Moore * RETURN: Status 100095b482a8SLen Brown * 100195b482a8SLen Brown * DESCRIPTION: Delete all namespace objects created when this table was loaded. 100295b482a8SLen Brown * 100395b482a8SLen Brown ******************************************************************************/ 100495b482a8SLen Brown 10058a335a23SBob Moore acpi_status acpi_tb_delete_namespace_by_owner(u32 table_index) 100695b482a8SLen Brown { 100795b482a8SLen Brown acpi_owner_id owner_id; 10088a335a23SBob Moore acpi_status status; 100995b482a8SLen Brown 10108a335a23SBob Moore ACPI_FUNCTION_TRACE(tb_delete_namespace_by_owner); 10118a335a23SBob Moore 10128a335a23SBob Moore status = acpi_ut_acquire_mutex(ACPI_MTX_TABLES); 10138a335a23SBob Moore if (ACPI_FAILURE(status)) { 10148a335a23SBob Moore return_ACPI_STATUS(status); 101595b482a8SLen Brown } 101695b482a8SLen Brown 1017b9ee2043SBob Moore if (table_index >= acpi_gbl_root_table_list.current_table_count) { 10188a335a23SBob Moore 10198a335a23SBob Moore /* The table index does not exist */ 10208a335a23SBob Moore 102195b482a8SLen Brown (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); 10228a335a23SBob Moore return_ACPI_STATUS(AE_NOT_EXIST); 10238a335a23SBob Moore } 10248a335a23SBob Moore 10258a335a23SBob Moore /* Get the owner ID for this table, used to delete namespace nodes */ 10268a335a23SBob Moore 10278a335a23SBob Moore owner_id = acpi_gbl_root_table_list.tables[table_index].owner_id; 10288a335a23SBob Moore (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); 10298a335a23SBob Moore 10308a335a23SBob Moore /* 10318a335a23SBob Moore * Need to acquire the namespace writer lock to prevent interference 10328a335a23SBob Moore * with any concurrent namespace walks. The interpreter must be 10338a335a23SBob Moore * released during the deletion since the acquisition of the deletion 10348a335a23SBob Moore * lock may block, and also since the execution of a namespace walk 10358a335a23SBob Moore * must be allowed to use the interpreter. 10368a335a23SBob Moore */ 1037e4c1ebfcSBob Moore (void)acpi_ut_release_mutex(ACPI_MTX_INTERPRETER); 10388a335a23SBob Moore status = acpi_ut_acquire_write_lock(&acpi_gbl_namespace_rw_lock); 10398a335a23SBob Moore 104095b482a8SLen Brown acpi_ns_delete_namespace_by_owner(owner_id); 10418a335a23SBob Moore if (ACPI_FAILURE(status)) { 10428a335a23SBob Moore return_ACPI_STATUS(status); 10438a335a23SBob Moore } 10448a335a23SBob Moore 10458a335a23SBob Moore acpi_ut_release_write_lock(&acpi_gbl_namespace_rw_lock); 10468a335a23SBob Moore 10478a335a23SBob Moore status = acpi_ut_acquire_mutex(ACPI_MTX_INTERPRETER); 10488a335a23SBob Moore return_ACPI_STATUS(status); 104995b482a8SLen Brown } 105095b482a8SLen Brown 105195b482a8SLen Brown /******************************************************************************* 105295b482a8SLen Brown * 105395b482a8SLen Brown * FUNCTION: acpi_tb_allocate_owner_id 105495b482a8SLen Brown * 105595b482a8SLen Brown * PARAMETERS: table_index - Table index 105695b482a8SLen Brown * 105795b482a8SLen Brown * RETURN: Status 105895b482a8SLen Brown * 105995b482a8SLen Brown * DESCRIPTION: Allocates owner_id in table_desc 106095b482a8SLen Brown * 106195b482a8SLen Brown ******************************************************************************/ 106295b482a8SLen Brown 106395b482a8SLen Brown acpi_status acpi_tb_allocate_owner_id(u32 table_index) 106495b482a8SLen Brown { 106595b482a8SLen Brown acpi_status status = AE_BAD_PARAMETER; 106695b482a8SLen Brown 106795b482a8SLen Brown ACPI_FUNCTION_TRACE(tb_allocate_owner_id); 106895b482a8SLen Brown 106995b482a8SLen Brown (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); 1070b9ee2043SBob Moore if (table_index < acpi_gbl_root_table_list.current_table_count) { 107195b482a8SLen Brown status = acpi_ut_allocate_owner_id 107295b482a8SLen Brown (&(acpi_gbl_root_table_list.tables[table_index].owner_id)); 107395b482a8SLen Brown } 107495b482a8SLen Brown 107595b482a8SLen Brown (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); 107695b482a8SLen Brown return_ACPI_STATUS(status); 107795b482a8SLen Brown } 107895b482a8SLen Brown 107995b482a8SLen Brown /******************************************************************************* 108095b482a8SLen Brown * 108195b482a8SLen Brown * FUNCTION: acpi_tb_release_owner_id 108295b482a8SLen Brown * 108395b482a8SLen Brown * PARAMETERS: table_index - Table index 108495b482a8SLen Brown * 108595b482a8SLen Brown * RETURN: Status 108695b482a8SLen Brown * 108795b482a8SLen Brown * DESCRIPTION: Releases owner_id in table_desc 108895b482a8SLen Brown * 108995b482a8SLen Brown ******************************************************************************/ 109095b482a8SLen Brown 109195b482a8SLen Brown acpi_status acpi_tb_release_owner_id(u32 table_index) 109295b482a8SLen Brown { 109395b482a8SLen Brown acpi_status status = AE_BAD_PARAMETER; 109495b482a8SLen Brown 109595b482a8SLen Brown ACPI_FUNCTION_TRACE(tb_release_owner_id); 109695b482a8SLen Brown 109795b482a8SLen Brown (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); 1098b9ee2043SBob Moore if (table_index < acpi_gbl_root_table_list.current_table_count) { 109995b482a8SLen Brown acpi_ut_release_owner_id(& 110095b482a8SLen Brown (acpi_gbl_root_table_list. 110195b482a8SLen Brown tables[table_index].owner_id)); 110295b482a8SLen Brown status = AE_OK; 110395b482a8SLen Brown } 110495b482a8SLen Brown 110595b482a8SLen Brown (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); 110695b482a8SLen Brown return_ACPI_STATUS(status); 110795b482a8SLen Brown } 110895b482a8SLen Brown 110995b482a8SLen Brown /******************************************************************************* 111095b482a8SLen Brown * 111195b482a8SLen Brown * FUNCTION: acpi_tb_get_owner_id 111295b482a8SLen Brown * 111395b482a8SLen Brown * PARAMETERS: table_index - Table index 111495b482a8SLen Brown * owner_id - Where the table owner_id is returned 111595b482a8SLen Brown * 111695b482a8SLen Brown * RETURN: Status 111795b482a8SLen Brown * 111895b482a8SLen Brown * DESCRIPTION: returns owner_id for the ACPI table 111995b482a8SLen Brown * 112095b482a8SLen Brown ******************************************************************************/ 112195b482a8SLen Brown 112295b482a8SLen Brown acpi_status acpi_tb_get_owner_id(u32 table_index, acpi_owner_id * owner_id) 112395b482a8SLen Brown { 112495b482a8SLen Brown acpi_status status = AE_BAD_PARAMETER; 112595b482a8SLen Brown 112695b482a8SLen Brown ACPI_FUNCTION_TRACE(tb_get_owner_id); 112795b482a8SLen Brown 112895b482a8SLen Brown (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); 1129b9ee2043SBob Moore if (table_index < acpi_gbl_root_table_list.current_table_count) { 113095b482a8SLen Brown *owner_id = 113195b482a8SLen Brown acpi_gbl_root_table_list.tables[table_index].owner_id; 113295b482a8SLen Brown status = AE_OK; 113395b482a8SLen Brown } 113495b482a8SLen Brown 113595b482a8SLen Brown (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); 113695b482a8SLen Brown return_ACPI_STATUS(status); 113795b482a8SLen Brown } 113895b482a8SLen Brown 113995b482a8SLen Brown /******************************************************************************* 114095b482a8SLen Brown * 114195b482a8SLen Brown * FUNCTION: acpi_tb_is_table_loaded 114295b482a8SLen Brown * 114395b482a8SLen Brown * PARAMETERS: table_index - Table index 114495b482a8SLen Brown * 114595b482a8SLen Brown * RETURN: Table Loaded Flag 114695b482a8SLen Brown * 114795b482a8SLen Brown ******************************************************************************/ 114895b482a8SLen Brown 114995b482a8SLen Brown u8 acpi_tb_is_table_loaded(u32 table_index) 115095b482a8SLen Brown { 115195b482a8SLen Brown u8 is_loaded = FALSE; 115295b482a8SLen Brown 115395b482a8SLen Brown (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); 1154b9ee2043SBob Moore if (table_index < acpi_gbl_root_table_list.current_table_count) { 115595b482a8SLen Brown is_loaded = (u8) 1156ec41f193SBob Moore (acpi_gbl_root_table_list.tables[table_index].flags & 1157ec41f193SBob Moore ACPI_TABLE_IS_LOADED); 115895b482a8SLen Brown } 115995b482a8SLen Brown 116095b482a8SLen Brown (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); 116195b482a8SLen Brown return (is_loaded); 116295b482a8SLen Brown } 116395b482a8SLen Brown 116495b482a8SLen Brown /******************************************************************************* 116595b482a8SLen Brown * 116695b482a8SLen Brown * FUNCTION: acpi_tb_set_table_loaded_flag 116795b482a8SLen Brown * 116895b482a8SLen Brown * PARAMETERS: table_index - Table index 116995b482a8SLen Brown * is_loaded - TRUE if table is loaded, FALSE otherwise 117095b482a8SLen Brown * 117195b482a8SLen Brown * RETURN: None 117295b482a8SLen Brown * 117395b482a8SLen Brown * DESCRIPTION: Sets the table loaded flag to either TRUE or FALSE. 117495b482a8SLen Brown * 117595b482a8SLen Brown ******************************************************************************/ 117695b482a8SLen Brown 117795b482a8SLen Brown void acpi_tb_set_table_loaded_flag(u32 table_index, u8 is_loaded) 117895b482a8SLen Brown { 117995b482a8SLen Brown 118095b482a8SLen Brown (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); 1181b9ee2043SBob Moore if (table_index < acpi_gbl_root_table_list.current_table_count) { 118295b482a8SLen Brown if (is_loaded) { 118395b482a8SLen Brown acpi_gbl_root_table_list.tables[table_index].flags |= 118495b482a8SLen Brown ACPI_TABLE_IS_LOADED; 118595b482a8SLen Brown } else { 118695b482a8SLen Brown acpi_gbl_root_table_list.tables[table_index].flags &= 118795b482a8SLen Brown ~ACPI_TABLE_IS_LOADED; 118895b482a8SLen Brown } 118995b482a8SLen Brown } 119095b482a8SLen Brown 119195b482a8SLen Brown (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); 119295b482a8SLen Brown } 1193