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 52*86dfc6f3SLv Zheng /* Local prototypes */ 53*86dfc6f3SLv Zheng static acpi_status 54*86dfc6f3SLv Zheng acpi_tb_acquire_temporal_table(struct acpi_table_desc *table_desc, 55*86dfc6f3SLv Zheng acpi_physical_address address, u8 flags); 56*86dfc6f3SLv Zheng 57*86dfc6f3SLv Zheng static void acpi_tb_release_temporal_table(struct acpi_table_desc *table_desc); 58*86dfc6f3SLv Zheng 59*86dfc6f3SLv Zheng static acpi_status acpi_tb_acquire_root_table_entry(u32 *table_index); 60*86dfc6f3SLv Zheng 61*86dfc6f3SLv Zheng static u8 62*86dfc6f3SLv Zheng acpi_tb_is_equivalent_table(struct acpi_table_desc *table_desc, 63*86dfc6f3SLv Zheng u32 table_index); 64*86dfc6f3SLv 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 ******************************************************************************/ 80*86dfc6f3SLv 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) { 89dc156adfSLv Zheng case ACPI_TABLE_ORIGIN_MAPPED: 90dc156adfSLv Zheng 917f9fc99cSLv Zheng table = 927f9fc99cSLv Zheng acpi_os_map_memory(table_desc->address, table_desc->length); 93dc156adfSLv Zheng break; 94dc156adfSLv Zheng 95dc156adfSLv Zheng case ACPI_TABLE_ORIGIN_ALLOCATED: 96dc156adfSLv Zheng case ACPI_TABLE_ORIGIN_UNKNOWN: 97dc156adfSLv Zheng case ACPI_TABLE_ORIGIN_OVERRIDE: 98dc156adfSLv Zheng 997f9fc99cSLv Zheng table = 100dc156adfSLv Zheng ACPI_CAST_PTR(struct acpi_table_header, 101dc156adfSLv Zheng table_desc->address); 102dc156adfSLv Zheng break; 103dc156adfSLv Zheng 104dc156adfSLv Zheng default: 105dc156adfSLv Zheng 106dc156adfSLv Zheng break; 10795b482a8SLen Brown } 1085582982dSLv Zheng 1097f9fc99cSLv Zheng /* Table is not valid yet */ 1107f9fc99cSLv Zheng 1117f9fc99cSLv Zheng if (!table) { 1127f9fc99cSLv Zheng return (AE_NO_MEMORY); 1137f9fc99cSLv Zheng } 1147f9fc99cSLv Zheng 1157f9fc99cSLv Zheng /* Fill the return values */ 1167f9fc99cSLv Zheng 1177f9fc99cSLv Zheng *table_ptr = table; 1187f9fc99cSLv Zheng *table_length = table_desc->length; 1197f9fc99cSLv Zheng *table_flags = table_desc->flags; 1207f9fc99cSLv Zheng 1217f9fc99cSLv Zheng return (AE_OK); 1227f9fc99cSLv Zheng } 1237f9fc99cSLv Zheng 1247f9fc99cSLv Zheng /******************************************************************************* 1257f9fc99cSLv Zheng * 1267f9fc99cSLv Zheng * FUNCTION: acpi_tb_release_table 1277f9fc99cSLv Zheng * 1287f9fc99cSLv Zheng * PARAMETERS: table - Pointer for the table 1297f9fc99cSLv Zheng * table_length - Length for the table 1307f9fc99cSLv Zheng * table_flags - Allocation flags for the table 1317f9fc99cSLv Zheng * 1327f9fc99cSLv Zheng * RETURN: None 1337f9fc99cSLv Zheng * 1347f9fc99cSLv Zheng * DESCRIPTION: Release a table. The reversal of acpi_tb_acquire_table(). 1357f9fc99cSLv Zheng * 1367f9fc99cSLv Zheng ******************************************************************************/ 1377f9fc99cSLv Zheng 1387f9fc99cSLv Zheng void 1397f9fc99cSLv Zheng acpi_tb_release_table(struct acpi_table_header *table, 1407f9fc99cSLv Zheng u32 table_length, u8 table_flags) 1417f9fc99cSLv Zheng { 1427f9fc99cSLv Zheng switch (table_flags & ACPI_TABLE_ORIGIN_MASK) { 1437f9fc99cSLv Zheng case ACPI_TABLE_ORIGIN_MAPPED: 1447f9fc99cSLv Zheng 1457f9fc99cSLv Zheng acpi_os_unmap_memory(table, table_length); 1467f9fc99cSLv Zheng break; 1477f9fc99cSLv Zheng 1487f9fc99cSLv Zheng case ACPI_TABLE_ORIGIN_ALLOCATED: 1497f9fc99cSLv Zheng case ACPI_TABLE_ORIGIN_UNKNOWN: 1507f9fc99cSLv Zheng case ACPI_TABLE_ORIGIN_OVERRIDE: 1517f9fc99cSLv Zheng default: 1527f9fc99cSLv Zheng 1537f9fc99cSLv Zheng break; 1547f9fc99cSLv Zheng } 1557f9fc99cSLv Zheng } 1567f9fc99cSLv Zheng 1577f9fc99cSLv Zheng /****************************************************************************** 1587f9fc99cSLv Zheng * 1597f9fc99cSLv Zheng * FUNCTION: acpi_tb_validate_table 1607f9fc99cSLv Zheng * 1617f9fc99cSLv Zheng * PARAMETERS: table_desc - Table descriptor 1627f9fc99cSLv Zheng * 1637f9fc99cSLv Zheng * RETURN: Status 1647f9fc99cSLv Zheng * 165*86dfc6f3SLv Zheng * DESCRIPTION: This function is called to validate the table, the returned 166*86dfc6f3SLv Zheng * table descriptor is in "VALIDATED" state. 1677f9fc99cSLv Zheng * 1687f9fc99cSLv Zheng *****************************************************************************/ 1697f9fc99cSLv Zheng 1707f9fc99cSLv Zheng acpi_status acpi_tb_validate_table(struct acpi_table_desc *table_desc) 1717f9fc99cSLv Zheng { 1727f9fc99cSLv Zheng acpi_status status = AE_OK; 1737f9fc99cSLv Zheng 1747f9fc99cSLv Zheng ACPI_FUNCTION_TRACE(tb_validate_table); 1757f9fc99cSLv Zheng 1767f9fc99cSLv Zheng /* Validate the table if necessary */ 1777f9fc99cSLv Zheng 17895b482a8SLen Brown if (!table_desc->pointer) { 1797f9fc99cSLv Zheng status = acpi_tb_acquire_table(table_desc, &table_desc->pointer, 1807f9fc99cSLv Zheng &table_desc->length, 1817f9fc99cSLv Zheng &table_desc->flags); 182*86dfc6f3SLv Zheng if (!table_desc->pointer) { 183*86dfc6f3SLv Zheng status = AE_NO_MEMORY; 18495b482a8SLen Brown } 18595b482a8SLen Brown } 18695b482a8SLen Brown 18795b482a8SLen Brown return_ACPI_STATUS(status); 18895b482a8SLen Brown } 18995b482a8SLen Brown 19095b482a8SLen Brown /******************************************************************************* 19195b482a8SLen Brown * 1927f9fc99cSLv Zheng * FUNCTION: acpi_tb_invalidate_table 1937f9fc99cSLv Zheng * 1947f9fc99cSLv Zheng * PARAMETERS: table_desc - Table descriptor 1957f9fc99cSLv Zheng * 1967f9fc99cSLv Zheng * RETURN: None 1977f9fc99cSLv Zheng * 1987f9fc99cSLv Zheng * DESCRIPTION: Invalidate one internal ACPI table, this is reversal of 1997f9fc99cSLv Zheng * acpi_tb_validate_table(). 2007f9fc99cSLv Zheng * 2017f9fc99cSLv Zheng ******************************************************************************/ 2027f9fc99cSLv Zheng 2037f9fc99cSLv Zheng void acpi_tb_invalidate_table(struct acpi_table_desc *table_desc) 2047f9fc99cSLv Zheng { 2057f9fc99cSLv Zheng 2067f9fc99cSLv Zheng ACPI_FUNCTION_TRACE(tb_invalidate_table); 2077f9fc99cSLv Zheng 2087f9fc99cSLv Zheng /* Table must be validated */ 2097f9fc99cSLv Zheng 2107f9fc99cSLv Zheng if (!table_desc->pointer) { 2117f9fc99cSLv Zheng return_VOID; 2127f9fc99cSLv Zheng } 2137f9fc99cSLv Zheng 2147f9fc99cSLv Zheng acpi_tb_release_table(table_desc->pointer, table_desc->length, 2157f9fc99cSLv Zheng table_desc->flags); 2167f9fc99cSLv Zheng table_desc->pointer = NULL; 2177f9fc99cSLv Zheng 2187f9fc99cSLv Zheng return_VOID; 2197f9fc99cSLv Zheng } 2207f9fc99cSLv Zheng 221*86dfc6f3SLv Zheng /****************************************************************************** 2227f9fc99cSLv Zheng * 223*86dfc6f3SLv Zheng * FUNCTION: acpi_tb_verify_table 22495b482a8SLen Brown * 22595b482a8SLen Brown * PARAMETERS: table_desc - Table descriptor 226*86dfc6f3SLv Zheng * signature - Table signature to verify 22795b482a8SLen Brown * 22895b482a8SLen Brown * RETURN: Status 22995b482a8SLen Brown * 230*86dfc6f3SLv Zheng * DESCRIPTION: This function is called to validate and verify the table, the 231*86dfc6f3SLv Zheng * returned table descriptor is in "VALIDATED" state. 232*86dfc6f3SLv Zheng * 233*86dfc6f3SLv Zheng *****************************************************************************/ 234*86dfc6f3SLv Zheng 235*86dfc6f3SLv Zheng acpi_status 236*86dfc6f3SLv Zheng acpi_tb_verify_table(struct acpi_table_desc *table_desc, char *signature) 237*86dfc6f3SLv Zheng { 238*86dfc6f3SLv Zheng acpi_status status = AE_OK; 239*86dfc6f3SLv Zheng 240*86dfc6f3SLv Zheng ACPI_FUNCTION_TRACE(tb_verify_table); 241*86dfc6f3SLv Zheng 242*86dfc6f3SLv Zheng /* Validate the table */ 243*86dfc6f3SLv Zheng 244*86dfc6f3SLv Zheng status = acpi_tb_validate_table(table_desc); 245*86dfc6f3SLv Zheng if (ACPI_FAILURE(status)) { 246*86dfc6f3SLv Zheng return_ACPI_STATUS(AE_NO_MEMORY); 247*86dfc6f3SLv Zheng } 248*86dfc6f3SLv Zheng 249*86dfc6f3SLv Zheng /* If a particular signature is expected (DSDT/FACS), it must match */ 250*86dfc6f3SLv Zheng 251*86dfc6f3SLv Zheng if (signature && !ACPI_COMPARE_NAME(&table_desc->signature, signature)) { 252*86dfc6f3SLv Zheng ACPI_BIOS_ERROR((AE_INFO, 253*86dfc6f3SLv Zheng "Invalid signature 0x%X for ACPI table, expected [%s]", 254*86dfc6f3SLv Zheng table_desc->signature.integer, signature)); 255*86dfc6f3SLv Zheng status = AE_BAD_SIGNATURE; 256*86dfc6f3SLv Zheng goto invalidate_and_exit; 257*86dfc6f3SLv Zheng } 258*86dfc6f3SLv Zheng 259*86dfc6f3SLv Zheng /* Verify the checksum */ 260*86dfc6f3SLv Zheng 261*86dfc6f3SLv Zheng status = 262*86dfc6f3SLv Zheng acpi_tb_verify_checksum(table_desc->pointer, table_desc->length); 263*86dfc6f3SLv Zheng if (ACPI_FAILURE(status)) { 264*86dfc6f3SLv Zheng ACPI_EXCEPTION((AE_INFO, AE_NO_MEMORY, 265*86dfc6f3SLv Zheng "%4.4s " ACPI_PRINTF_UINT 266*86dfc6f3SLv Zheng " Attempted table install failed", 267*86dfc6f3SLv Zheng acpi_ut_valid_acpi_name(table_desc->signature. 268*86dfc6f3SLv Zheng ascii) ? table_desc-> 269*86dfc6f3SLv Zheng signature.ascii : "????", 270*86dfc6f3SLv Zheng ACPI_FORMAT_TO_UINT(table_desc->address))); 271*86dfc6f3SLv Zheng goto invalidate_and_exit; 272*86dfc6f3SLv Zheng } 273*86dfc6f3SLv Zheng 274*86dfc6f3SLv Zheng return_ACPI_STATUS(AE_OK); 275*86dfc6f3SLv Zheng 276*86dfc6f3SLv Zheng invalidate_and_exit: 277*86dfc6f3SLv Zheng acpi_tb_invalidate_table(table_desc); 278*86dfc6f3SLv Zheng return_ACPI_STATUS(status); 279*86dfc6f3SLv Zheng } 280*86dfc6f3SLv Zheng 281*86dfc6f3SLv Zheng /******************************************************************************* 282*86dfc6f3SLv Zheng * 283*86dfc6f3SLv Zheng * FUNCTION: acpi_tb_install_table 284*86dfc6f3SLv Zheng * 285*86dfc6f3SLv Zheng * PARAMETERS: table_desc - Table descriptor 286*86dfc6f3SLv Zheng * address - Physical address of the table 287*86dfc6f3SLv Zheng * flags - Allocation flags of the table 288*86dfc6f3SLv Zheng * table - Pointer to the table 289*86dfc6f3SLv Zheng * 290*86dfc6f3SLv Zheng * RETURN: None 291*86dfc6f3SLv Zheng * 292*86dfc6f3SLv Zheng * DESCRIPTION: Install an ACPI table into the global data structure. 293*86dfc6f3SLv Zheng * 294*86dfc6f3SLv Zheng ******************************************************************************/ 295*86dfc6f3SLv Zheng 296*86dfc6f3SLv Zheng void 297*86dfc6f3SLv Zheng acpi_tb_install_table(struct acpi_table_desc *table_desc, 298*86dfc6f3SLv Zheng acpi_physical_address address, 299*86dfc6f3SLv Zheng u8 flags, struct acpi_table_header *table) 300*86dfc6f3SLv Zheng { 301*86dfc6f3SLv Zheng /* 302*86dfc6f3SLv Zheng * Initialize the table entry. Set the pointer to NULL, since the 303*86dfc6f3SLv Zheng * table is not fully mapped at this time. 304*86dfc6f3SLv Zheng */ 305*86dfc6f3SLv Zheng ACPI_MEMSET(table_desc, 0, sizeof(struct acpi_table_desc)); 306*86dfc6f3SLv Zheng table_desc->address = address; 307*86dfc6f3SLv Zheng table_desc->length = table->length; 308*86dfc6f3SLv Zheng table_desc->flags = flags; 309*86dfc6f3SLv Zheng ACPI_MOVE_32_TO_32(table_desc->signature.ascii, table->signature); 310*86dfc6f3SLv Zheng } 311*86dfc6f3SLv Zheng 312*86dfc6f3SLv Zheng /******************************************************************************* 313*86dfc6f3SLv Zheng * 314*86dfc6f3SLv Zheng * FUNCTION: acpi_tb_acquire_temporal_table 315*86dfc6f3SLv Zheng * 316*86dfc6f3SLv Zheng * PARAMETERS: table_desc - Table descriptor to be acquired 317*86dfc6f3SLv Zheng * address - Address of the table 318*86dfc6f3SLv Zheng * flags - Allocation flags of the table 319*86dfc6f3SLv Zheng * 320*86dfc6f3SLv Zheng * RETURN: Status 321*86dfc6f3SLv Zheng * 322*86dfc6f3SLv Zheng * DESCRIPTION: This function validates the table header to obtain the length 323*86dfc6f3SLv Zheng * of a table and fills the table descriptor to make its state as 324*86dfc6f3SLv Zheng * "INSTALLED". Such table descriptor is only used for verified 325*86dfc6f3SLv Zheng * installation. 326*86dfc6f3SLv Zheng * 327*86dfc6f3SLv Zheng ******************************************************************************/ 328*86dfc6f3SLv Zheng 329*86dfc6f3SLv Zheng static acpi_status 330*86dfc6f3SLv Zheng acpi_tb_acquire_temporal_table(struct acpi_table_desc *table_desc, 331*86dfc6f3SLv Zheng acpi_physical_address address, u8 flags) 332*86dfc6f3SLv Zheng { 333*86dfc6f3SLv Zheng struct acpi_table_header *table_header; 334*86dfc6f3SLv Zheng 335*86dfc6f3SLv Zheng switch (flags & ACPI_TABLE_ORIGIN_MASK) { 336*86dfc6f3SLv Zheng case ACPI_TABLE_ORIGIN_MAPPED: 337*86dfc6f3SLv Zheng 338*86dfc6f3SLv Zheng /* Try to obtain the length of the table */ 339*86dfc6f3SLv Zheng 340*86dfc6f3SLv Zheng table_header = 341*86dfc6f3SLv Zheng acpi_os_map_memory(address, 342*86dfc6f3SLv Zheng sizeof(struct acpi_table_header)); 343*86dfc6f3SLv Zheng if (!table_header) { 344*86dfc6f3SLv Zheng return (AE_NO_MEMORY); 345*86dfc6f3SLv Zheng } 346*86dfc6f3SLv Zheng acpi_tb_install_table(table_desc, address, flags, table_header); 347*86dfc6f3SLv Zheng acpi_os_unmap_memory(table_header, 348*86dfc6f3SLv Zheng sizeof(struct acpi_table_header)); 349*86dfc6f3SLv Zheng return (AE_OK); 350*86dfc6f3SLv Zheng 351*86dfc6f3SLv Zheng case ACPI_TABLE_ORIGIN_ALLOCATED: 352*86dfc6f3SLv Zheng case ACPI_TABLE_ORIGIN_UNKNOWN: 353*86dfc6f3SLv Zheng case ACPI_TABLE_ORIGIN_OVERRIDE: 354*86dfc6f3SLv Zheng 355*86dfc6f3SLv Zheng table_header = ACPI_CAST_PTR(struct acpi_table_header, address); 356*86dfc6f3SLv Zheng if (!table_header) { 357*86dfc6f3SLv Zheng return (AE_NO_MEMORY); 358*86dfc6f3SLv Zheng } 359*86dfc6f3SLv Zheng acpi_tb_install_table(table_desc, address, flags, table_header); 360*86dfc6f3SLv Zheng return (AE_OK); 361*86dfc6f3SLv Zheng 362*86dfc6f3SLv Zheng default: 363*86dfc6f3SLv Zheng 364*86dfc6f3SLv Zheng break; 365*86dfc6f3SLv Zheng } 366*86dfc6f3SLv Zheng 367*86dfc6f3SLv Zheng /* Table is not valid yet */ 368*86dfc6f3SLv Zheng 369*86dfc6f3SLv Zheng return (AE_NO_MEMORY); 370*86dfc6f3SLv Zheng } 371*86dfc6f3SLv Zheng 372*86dfc6f3SLv Zheng /******************************************************************************* 373*86dfc6f3SLv Zheng * 374*86dfc6f3SLv Zheng * FUNCTION: acpi_tb_release_temporal_table 375*86dfc6f3SLv Zheng * 376*86dfc6f3SLv Zheng * PARAMETERS: table_desc - Table descriptor to be released 377*86dfc6f3SLv Zheng * 378*86dfc6f3SLv Zheng * RETURN: Status 379*86dfc6f3SLv Zheng * 380*86dfc6f3SLv Zheng * DESCRIPTION: The reversal of acpi_tb_acquire_temporal_table(). 381*86dfc6f3SLv Zheng * 382*86dfc6f3SLv Zheng ******************************************************************************/ 383*86dfc6f3SLv Zheng 384*86dfc6f3SLv Zheng static void acpi_tb_release_temporal_table(struct acpi_table_desc *table_desc) 385*86dfc6f3SLv Zheng { 386*86dfc6f3SLv Zheng /* 387*86dfc6f3SLv Zheng * Note that the .Address is maintained by the callers of 388*86dfc6f3SLv Zheng * acpi_tb_acquire_temporal_table(), thus do not invoke acpi_tb_uninstall_table() 389*86dfc6f3SLv Zheng * where .Address will be freed. 390*86dfc6f3SLv Zheng */ 391*86dfc6f3SLv Zheng acpi_tb_invalidate_table(table_desc); 392*86dfc6f3SLv Zheng } 393*86dfc6f3SLv Zheng 394*86dfc6f3SLv Zheng /******************************************************************************* 395*86dfc6f3SLv Zheng * 396*86dfc6f3SLv Zheng * FUNCTION: acpi_tb_install_and_override_table 397*86dfc6f3SLv Zheng * 398*86dfc6f3SLv Zheng * PARAMETERS: table_index - Index into root table array 399*86dfc6f3SLv Zheng * new_table_desc - New table descriptor to install 400*86dfc6f3SLv Zheng * 401*86dfc6f3SLv Zheng * RETURN: None 402*86dfc6f3SLv Zheng * 403*86dfc6f3SLv Zheng * DESCRIPTION: Install an ACPI table into the global data structure. The 404*86dfc6f3SLv Zheng * table override mechanism is called to allow the host 405*86dfc6f3SLv Zheng * OS to replace any table before it is installed in the root 406*86dfc6f3SLv Zheng * table array. 407*86dfc6f3SLv Zheng * 408*86dfc6f3SLv Zheng ******************************************************************************/ 409*86dfc6f3SLv Zheng 410*86dfc6f3SLv Zheng void 411*86dfc6f3SLv Zheng acpi_tb_install_and_override_table(u32 table_index, 412*86dfc6f3SLv Zheng struct acpi_table_desc *new_table_desc) 413*86dfc6f3SLv Zheng { 414*86dfc6f3SLv Zheng if (table_index >= acpi_gbl_root_table_list.current_table_count) { 415*86dfc6f3SLv Zheng return; 416*86dfc6f3SLv Zheng } 417*86dfc6f3SLv Zheng 418*86dfc6f3SLv Zheng /* 419*86dfc6f3SLv Zheng * ACPI Table Override: 420*86dfc6f3SLv Zheng * 421*86dfc6f3SLv Zheng * Before we install the table, let the host OS override it with a new 422*86dfc6f3SLv Zheng * one if desired. Any table within the RSDT/XSDT can be replaced, 423*86dfc6f3SLv Zheng * including the DSDT which is pointed to by the FADT. 424*86dfc6f3SLv Zheng */ 425*86dfc6f3SLv Zheng acpi_tb_override_table(new_table_desc); 426*86dfc6f3SLv Zheng 427*86dfc6f3SLv Zheng acpi_tb_install_table(&acpi_gbl_root_table_list.tables[table_index], 428*86dfc6f3SLv Zheng new_table_desc->address, new_table_desc->flags, 429*86dfc6f3SLv Zheng new_table_desc->pointer); 430*86dfc6f3SLv Zheng 431*86dfc6f3SLv Zheng acpi_tb_print_table_header(new_table_desc->address, 432*86dfc6f3SLv Zheng new_table_desc->pointer); 433*86dfc6f3SLv Zheng 434*86dfc6f3SLv Zheng /* Set the global integer width (based upon revision of the DSDT) */ 435*86dfc6f3SLv Zheng 436*86dfc6f3SLv Zheng if (table_index == ACPI_TABLE_INDEX_DSDT) { 437*86dfc6f3SLv Zheng acpi_ut_set_integer_width(new_table_desc->pointer->revision); 438*86dfc6f3SLv Zheng } 439*86dfc6f3SLv Zheng } 440*86dfc6f3SLv Zheng 441*86dfc6f3SLv Zheng /******************************************************************************* 442*86dfc6f3SLv Zheng * 443*86dfc6f3SLv Zheng * FUNCTION: acpi_tb_install_fixed_table 444*86dfc6f3SLv Zheng * 445*86dfc6f3SLv Zheng * PARAMETERS: address - Physical address of DSDT or FACS 446*86dfc6f3SLv Zheng * signature - Table signature, NULL if no need to 447*86dfc6f3SLv Zheng * match 448*86dfc6f3SLv Zheng * table_index - Index into root table array 449*86dfc6f3SLv Zheng * 450*86dfc6f3SLv Zheng * RETURN: Status 451*86dfc6f3SLv Zheng * 452*86dfc6f3SLv Zheng * DESCRIPTION: Install a fixed ACPI table (DSDT/FACS) into the global data 453*86dfc6f3SLv Zheng * structure. 45495b482a8SLen Brown * 45595b482a8SLen Brown ******************************************************************************/ 45695b482a8SLen Brown 45795b482a8SLen Brown acpi_status 458*86dfc6f3SLv Zheng acpi_tb_install_fixed_table(acpi_physical_address address, 459*86dfc6f3SLv Zheng char *signature, u32 table_index) 460*86dfc6f3SLv Zheng { 461*86dfc6f3SLv Zheng struct acpi_table_desc new_table_desc; 462*86dfc6f3SLv Zheng acpi_status status; 463*86dfc6f3SLv Zheng 464*86dfc6f3SLv Zheng ACPI_FUNCTION_TRACE(tb_install_fixed_table); 465*86dfc6f3SLv Zheng 466*86dfc6f3SLv Zheng if (!address) { 467*86dfc6f3SLv Zheng ACPI_ERROR((AE_INFO, 468*86dfc6f3SLv Zheng "Null physical address for ACPI table [%s]", 469*86dfc6f3SLv Zheng signature)); 470*86dfc6f3SLv Zheng return (AE_NO_MEMORY); 471*86dfc6f3SLv Zheng } 472*86dfc6f3SLv Zheng 473*86dfc6f3SLv Zheng /* Fill a table descriptor for validation */ 474*86dfc6f3SLv Zheng 475*86dfc6f3SLv Zheng status = acpi_tb_acquire_temporal_table(&new_table_desc, address, 476*86dfc6f3SLv Zheng ACPI_TABLE_ORIGIN_MAPPED); 477*86dfc6f3SLv Zheng if (ACPI_FAILURE(status)) { 478*86dfc6f3SLv Zheng ACPI_ERROR((AE_INFO, "Could not acquire table length at %p", 479*86dfc6f3SLv Zheng ACPI_CAST_PTR(void, address))); 480*86dfc6f3SLv Zheng return_ACPI_STATUS(status); 481*86dfc6f3SLv Zheng } 482*86dfc6f3SLv Zheng 483*86dfc6f3SLv Zheng /* Validate and verify a table before installation */ 484*86dfc6f3SLv Zheng 485*86dfc6f3SLv Zheng status = acpi_tb_verify_table(&new_table_desc, signature); 486*86dfc6f3SLv Zheng if (ACPI_FAILURE(status)) { 487*86dfc6f3SLv Zheng goto release_and_exit; 488*86dfc6f3SLv Zheng } 489*86dfc6f3SLv Zheng 490*86dfc6f3SLv Zheng acpi_tb_install_and_override_table(table_index, &new_table_desc); 491*86dfc6f3SLv Zheng 492*86dfc6f3SLv Zheng release_and_exit: 493*86dfc6f3SLv Zheng 494*86dfc6f3SLv Zheng /* Release the temporal table descriptor */ 495*86dfc6f3SLv Zheng 496*86dfc6f3SLv Zheng acpi_tb_release_temporal_table(&new_table_desc); 497*86dfc6f3SLv Zheng return_ACPI_STATUS(status); 498*86dfc6f3SLv Zheng } 499*86dfc6f3SLv Zheng 500*86dfc6f3SLv Zheng /******************************************************************************* 501*86dfc6f3SLv Zheng * 502*86dfc6f3SLv Zheng * FUNCTION: acpi_tb_is_equivalent_table 503*86dfc6f3SLv Zheng * 504*86dfc6f3SLv Zheng * PARAMETERS: table_desc - Table 1 descriptor to be compared 505*86dfc6f3SLv Zheng * table_index - Index of table 2 to be compared 506*86dfc6f3SLv Zheng * 507*86dfc6f3SLv Zheng * RETURN: TRUE if 2 tables are equivalent 508*86dfc6f3SLv Zheng * 509*86dfc6f3SLv Zheng * DESCRIPTION: This function is called to compare a table with what have 510*86dfc6f3SLv Zheng * already been installed in the root table list. 511*86dfc6f3SLv Zheng * 512*86dfc6f3SLv Zheng ******************************************************************************/ 513*86dfc6f3SLv Zheng 514*86dfc6f3SLv Zheng static u8 515*86dfc6f3SLv Zheng acpi_tb_is_equivalent_table(struct acpi_table_desc *table_desc, u32 table_index) 516*86dfc6f3SLv Zheng { 517*86dfc6f3SLv Zheng acpi_status status = AE_OK; 518*86dfc6f3SLv Zheng u8 is_equivalent; 519*86dfc6f3SLv Zheng struct acpi_table_header *table; 520*86dfc6f3SLv Zheng u32 table_length; 521*86dfc6f3SLv Zheng u8 table_flags; 522*86dfc6f3SLv Zheng 523*86dfc6f3SLv Zheng status = 524*86dfc6f3SLv Zheng acpi_tb_acquire_table(&acpi_gbl_root_table_list.tables[table_index], 525*86dfc6f3SLv Zheng &table, &table_length, &table_flags); 526*86dfc6f3SLv Zheng if (ACPI_FAILURE(status)) { 527*86dfc6f3SLv Zheng return (FALSE); 528*86dfc6f3SLv Zheng } 529*86dfc6f3SLv Zheng 530*86dfc6f3SLv Zheng /* 531*86dfc6f3SLv Zheng * Check for a table match on the entire table length, 532*86dfc6f3SLv Zheng * not just the header. 533*86dfc6f3SLv Zheng */ 534*86dfc6f3SLv Zheng is_equivalent = (u8)((table_desc->length != table_length || 535*86dfc6f3SLv Zheng ACPI_MEMCMP(table_desc->pointer, table, 536*86dfc6f3SLv Zheng table_length)) ? FALSE : TRUE); 537*86dfc6f3SLv Zheng 538*86dfc6f3SLv Zheng /* Release the acquired table */ 539*86dfc6f3SLv Zheng 540*86dfc6f3SLv Zheng acpi_tb_release_table(table, table_length, table_flags); 541*86dfc6f3SLv Zheng 542*86dfc6f3SLv Zheng return (is_equivalent); 543*86dfc6f3SLv Zheng } 544*86dfc6f3SLv Zheng 545*86dfc6f3SLv Zheng /******************************************************************************* 546*86dfc6f3SLv Zheng * 547*86dfc6f3SLv Zheng * FUNCTION: acpi_tb_install_non_fixed_table 548*86dfc6f3SLv Zheng * 549*86dfc6f3SLv Zheng * PARAMETERS: address - Address of the table (might be a logical 550*86dfc6f3SLv Zheng * address depending on the table_flags) 551*86dfc6f3SLv Zheng * flags - Flags for the table 552*86dfc6f3SLv Zheng * reload - Whether reload should be performed 553*86dfc6f3SLv Zheng * table_index - Where the table index is returned 554*86dfc6f3SLv Zheng * 555*86dfc6f3SLv Zheng * RETURN: Status 556*86dfc6f3SLv Zheng * 557*86dfc6f3SLv Zheng * DESCRIPTION: This function is called to install an ACPI table that is 558*86dfc6f3SLv Zheng * neither DSDT nor FACS. 559*86dfc6f3SLv Zheng * When this function is called by "Load" or "LoadTable" opcodes, 560*86dfc6f3SLv Zheng * or by acpi_load_table() API, the "Reload" parameter is set. 561*86dfc6f3SLv Zheng * After sucessfully returning from this function, table is 562*86dfc6f3SLv Zheng * "INSTALLED" but not "VALIDATED". 563*86dfc6f3SLv Zheng * 564*86dfc6f3SLv Zheng ******************************************************************************/ 565*86dfc6f3SLv Zheng 566*86dfc6f3SLv Zheng acpi_status 567*86dfc6f3SLv Zheng acpi_tb_install_non_fixed_table(acpi_physical_address address, 568*86dfc6f3SLv Zheng u8 flags, u8 reload, u32 *table_index) 56995b482a8SLen Brown { 57095b482a8SLen Brown u32 i; 57195b482a8SLen Brown acpi_status status = AE_OK; 572*86dfc6f3SLv Zheng struct acpi_table_desc new_table_desc; 57395b482a8SLen Brown 574*86dfc6f3SLv Zheng ACPI_FUNCTION_TRACE(tb_install_non_fixed_table); 57595b482a8SLen Brown 576*86dfc6f3SLv Zheng /* Acquire a temporal table descriptor for validation */ 577*86dfc6f3SLv Zheng 578*86dfc6f3SLv Zheng status = 579*86dfc6f3SLv Zheng acpi_tb_acquire_temporal_table(&new_table_desc, address, flags); 580*86dfc6f3SLv Zheng if (ACPI_FAILURE(status)) { 581*86dfc6f3SLv Zheng ACPI_ERROR((AE_INFO, "Could not acquire table length at %p", 582*86dfc6f3SLv Zheng ACPI_CAST_PTR(void, address))); 58395b482a8SLen Brown return_ACPI_STATUS(status); 58495b482a8SLen Brown } 585*86dfc6f3SLv Zheng 586*86dfc6f3SLv Zheng /* Validate and verify a table before installation */ 587*86dfc6f3SLv Zheng 588*86dfc6f3SLv Zheng status = acpi_tb_verify_table(&new_table_desc, NULL); 589*86dfc6f3SLv Zheng if (ACPI_FAILURE(status)) { 590*86dfc6f3SLv Zheng goto release_and_exit; 59195b482a8SLen Brown } 59295b482a8SLen Brown 593*86dfc6f3SLv Zheng if (reload) { 59495b482a8SLen Brown /* 595c8cefe30SBob Moore * Validate the incoming table signature. 596c8cefe30SBob Moore * 597c8cefe30SBob Moore * 1) Originally, we checked the table signature for "SSDT" or "PSDT". 598c8cefe30SBob Moore * 2) We added support for OEMx tables, signature "OEM". 599c8cefe30SBob Moore * 3) Valid tables were encountered with a null signature, so we just 600c8cefe30SBob Moore * gave up on validating the signature, (05/2008). 601c8cefe30SBob Moore * 4) We encountered non-AML tables such as the MADT, which caused 602c8cefe30SBob Moore * interpreter errors and kernel faults. So now, we once again allow 603c8cefe30SBob Moore * only "SSDT", "OEMx", and now, also a null signature. (05/2011). 60495b482a8SLen Brown */ 605*86dfc6f3SLv Zheng if ((new_table_desc.signature.ascii[0] != 0x00) && 606*86dfc6f3SLv Zheng (!ACPI_COMPARE_NAME 607*86dfc6f3SLv Zheng (&new_table_desc.signature, ACPI_SIG_SSDT)) 608*86dfc6f3SLv Zheng && (ACPI_STRNCMP(new_table_desc.signature.ascii, "OEM", 3))) 609*86dfc6f3SLv Zheng { 6103b3ea775SBob Moore ACPI_BIOS_ERROR((AE_INFO, 6113b3ea775SBob Moore "Table has invalid signature [%4.4s] (0x%8.8X), " 6123b3ea775SBob Moore "must be SSDT or OEMx", 613*86dfc6f3SLv Zheng acpi_ut_valid_acpi_name(new_table_desc. 614*86dfc6f3SLv Zheng signature. 615*86dfc6f3SLv Zheng ascii) ? 616*86dfc6f3SLv Zheng new_table_desc.signature. 617*86dfc6f3SLv Zheng ascii : "????", 618*86dfc6f3SLv Zheng new_table_desc.signature.integer)); 619c8cefe30SBob Moore 620*86dfc6f3SLv Zheng status = AE_BAD_SIGNATURE; 621*86dfc6f3SLv Zheng goto release_and_exit; 622c8cefe30SBob Moore } 62395b482a8SLen Brown 62495b482a8SLen Brown /* Check if table is already registered */ 62595b482a8SLen Brown 626*86dfc6f3SLv Zheng for (i = 0; i < acpi_gbl_root_table_list.current_table_count; 627*86dfc6f3SLv Zheng ++i) { 62895b482a8SLen Brown /* 62995b482a8SLen Brown * Check for a table match on the entire table length, 63095b482a8SLen Brown * not just the header. 63195b482a8SLen Brown */ 632*86dfc6f3SLv Zheng if (!acpi_tb_is_equivalent_table(&new_table_desc, i)) { 63395b482a8SLen Brown continue; 63495b482a8SLen Brown } 63595b482a8SLen Brown 63695b482a8SLen Brown /* 63795b482a8SLen Brown * Note: the current mechanism does not unregister a table if it is 63895b482a8SLen Brown * dynamically unloaded. The related namespace entries are deleted, 63995b482a8SLen Brown * but the table remains in the root table list. 64095b482a8SLen Brown * 64195b482a8SLen Brown * The assumption here is that the number of different tables that 64295b482a8SLen Brown * will be loaded is actually small, and there is minimal overhead 64395b482a8SLen Brown * in just keeping the table in case it is needed again. 64495b482a8SLen Brown * 64595b482a8SLen Brown * If this assumption changes in the future (perhaps on large 64695b482a8SLen Brown * machines with many table load/unload operations), tables will 64795b482a8SLen Brown * need to be unregistered when they are unloaded, and slots in the 64895b482a8SLen Brown * root table list should be reused when empty. 64995b482a8SLen Brown */ 65095b482a8SLen Brown if (acpi_gbl_root_table_list.tables[i]. 65195b482a8SLen Brown flags & ACPI_TABLE_IS_LOADED) { 65295b482a8SLen Brown 65395b482a8SLen Brown /* Table is still loaded, this is an error */ 65495b482a8SLen Brown 65595b482a8SLen Brown status = AE_ALREADY_EXISTS; 656*86dfc6f3SLv Zheng goto release_and_exit; 65795b482a8SLen Brown } else { 658d3ccaff8SBob Moore /* 659*86dfc6f3SLv Zheng * Table was unloaded, allow it to be reloaded. 660*86dfc6f3SLv Zheng * As we are going to return AE_OK to the caller, we should 661*86dfc6f3SLv Zheng * take the responsibility of freeing the input descriptor. 662*86dfc6f3SLv Zheng * Refill the input descriptor to ensure 663*86dfc6f3SLv Zheng * acpi_tb_install_and_override_table() can be called again to 664*86dfc6f3SLv Zheng * indicate the re-installation. 665d3ccaff8SBob Moore */ 666*86dfc6f3SLv Zheng acpi_tb_uninstall_table(&new_table_desc); 667*86dfc6f3SLv Zheng *table_index = i; 668*86dfc6f3SLv Zheng (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); 669*86dfc6f3SLv Zheng return_ACPI_STATUS(AE_OK); 670*86dfc6f3SLv Zheng } 671*86dfc6f3SLv Zheng } 6727f9fc99cSLv Zheng } 673d3ccaff8SBob Moore 67495b482a8SLen Brown /* Add the table to the global root table list */ 67595b482a8SLen Brown 676*86dfc6f3SLv Zheng status = acpi_tb_acquire_root_table_entry(&i); 67795b482a8SLen Brown if (ACPI_FAILURE(status)) { 678*86dfc6f3SLv Zheng goto release_and_exit; 67995b482a8SLen Brown } 680*86dfc6f3SLv Zheng *table_index = i; 681*86dfc6f3SLv Zheng acpi_tb_install_and_override_table(i, &new_table_desc); 68295b482a8SLen Brown 683*86dfc6f3SLv Zheng release_and_exit: 68495b482a8SLen Brown 685*86dfc6f3SLv Zheng /* Release the temporal table descriptor */ 686*86dfc6f3SLv Zheng 687*86dfc6f3SLv Zheng acpi_tb_release_temporal_table(&new_table_desc); 68895b482a8SLen Brown return_ACPI_STATUS(status); 68995b482a8SLen Brown } 69095b482a8SLen Brown 69195b482a8SLen Brown /******************************************************************************* 69295b482a8SLen Brown * 6937f9fc99cSLv Zheng * FUNCTION: acpi_tb_override_table 694f7b004a1SBob Moore * 695*86dfc6f3SLv Zheng * PARAMETERS: old_table_desc - Validated table descriptor to be 696*86dfc6f3SLv Zheng * overridden 697f7b004a1SBob Moore * 698*86dfc6f3SLv Zheng * RETURN: None 699f7b004a1SBob Moore * 700f7b004a1SBob Moore * DESCRIPTION: Attempt table override by calling the OSL override functions. 701f7b004a1SBob Moore * Note: If the table is overridden, then the entire new table 7027f9fc99cSLv Zheng * is acquired and returned by this function. 703*86dfc6f3SLv Zheng * Before/after invocation, the table descriptor is in a state 704*86dfc6f3SLv Zheng * that is "VALIDATED". 705f7b004a1SBob Moore * 706f7b004a1SBob Moore ******************************************************************************/ 707f7b004a1SBob Moore 708*86dfc6f3SLv Zheng void acpi_tb_override_table(struct acpi_table_desc *old_table_desc) 709f7b004a1SBob Moore { 710f7b004a1SBob Moore acpi_status status; 711f7b004a1SBob Moore char *override_type; 7127f9fc99cSLv Zheng struct acpi_table_desc new_table_desc; 713*86dfc6f3SLv Zheng struct acpi_table_header *table; 714*86dfc6f3SLv Zheng acpi_physical_address address; 715*86dfc6f3SLv Zheng u32 length; 716f7b004a1SBob Moore 717f7b004a1SBob Moore /* (1) Attempt logical override (returns a logical address) */ 718f7b004a1SBob Moore 719*86dfc6f3SLv Zheng status = acpi_os_table_override(old_table_desc->pointer, &table); 720*86dfc6f3SLv Zheng if (ACPI_SUCCESS(status) && table) { 721*86dfc6f3SLv Zheng acpi_tb_acquire_temporal_table(&new_table_desc, 722*86dfc6f3SLv Zheng ACPI_PTR_TO_PHYSADDR(table), 723*86dfc6f3SLv Zheng ACPI_TABLE_ORIGIN_OVERRIDE); 724f7b004a1SBob Moore override_type = "Logical"; 725f7b004a1SBob Moore goto finish_override; 726f7b004a1SBob Moore } 727f7b004a1SBob Moore 728f7b004a1SBob Moore /* (2) Attempt physical override (returns a physical address) */ 729f7b004a1SBob Moore 730*86dfc6f3SLv Zheng status = acpi_os_physical_table_override(old_table_desc->pointer, 731*86dfc6f3SLv Zheng &address, &length); 732*86dfc6f3SLv Zheng if (ACPI_SUCCESS(status) && address && length) { 733*86dfc6f3SLv Zheng acpi_tb_acquire_temporal_table(&new_table_desc, address, 734*86dfc6f3SLv Zheng ACPI_TABLE_ORIGIN_MAPPED); 735f7b004a1SBob Moore override_type = "Physical"; 736f7b004a1SBob Moore goto finish_override; 737f7b004a1SBob Moore } 738f7b004a1SBob Moore 739*86dfc6f3SLv Zheng return; /* There was no override */ 740f7b004a1SBob Moore 741f7b004a1SBob Moore finish_override: 742f7b004a1SBob Moore 743*86dfc6f3SLv Zheng /* Validate and verify a table before overriding */ 744*86dfc6f3SLv Zheng 745*86dfc6f3SLv Zheng status = acpi_tb_verify_table(&new_table_desc, NULL); 7467f9fc99cSLv Zheng if (ACPI_FAILURE(status)) { 747*86dfc6f3SLv Zheng return; 7487f9fc99cSLv Zheng } 7497f9fc99cSLv Zheng 7502e19f8d0SBob Moore ACPI_INFO((AE_INFO, "%4.4s " ACPI_PRINTF_UINT 7512e19f8d0SBob Moore " %s table override, new table: " ACPI_PRINTF_UINT, 752*86dfc6f3SLv Zheng old_table_desc->signature.ascii, 753*86dfc6f3SLv Zheng ACPI_FORMAT_TO_UINT(old_table_desc->address), 7547f9fc99cSLv Zheng override_type, ACPI_FORMAT_TO_UINT(new_table_desc.address))); 755f7b004a1SBob Moore 756*86dfc6f3SLv Zheng /* We can now uninstall the original table */ 757f7b004a1SBob Moore 758*86dfc6f3SLv Zheng acpi_tb_uninstall_table(old_table_desc); 759f7b004a1SBob Moore 760*86dfc6f3SLv Zheng /* 761*86dfc6f3SLv Zheng * Replace the original table descriptor and keep its state as 762*86dfc6f3SLv Zheng * "VALIDATED". 763*86dfc6f3SLv Zheng */ 764*86dfc6f3SLv Zheng acpi_tb_install_table(old_table_desc, new_table_desc.address, 765*86dfc6f3SLv Zheng new_table_desc.flags, new_table_desc.pointer); 766*86dfc6f3SLv Zheng acpi_tb_validate_table(old_table_desc); 767f7b004a1SBob Moore 768*86dfc6f3SLv Zheng /* Release the temporal table descriptor */ 769f7b004a1SBob Moore 770*86dfc6f3SLv Zheng acpi_tb_release_temporal_table(&new_table_desc); 771f7b004a1SBob Moore } 772f7b004a1SBob Moore 773f7b004a1SBob Moore /******************************************************************************* 774f7b004a1SBob Moore * 77595b482a8SLen Brown * FUNCTION: acpi_tb_resize_root_table_list 77695b482a8SLen Brown * 77795b482a8SLen Brown * PARAMETERS: None 77895b482a8SLen Brown * 77995b482a8SLen Brown * RETURN: Status 78095b482a8SLen Brown * 78195b482a8SLen Brown * DESCRIPTION: Expand the size of global table array 78295b482a8SLen Brown * 78395b482a8SLen Brown ******************************************************************************/ 78495b482a8SLen Brown 78595b482a8SLen Brown acpi_status acpi_tb_resize_root_table_list(void) 78695b482a8SLen Brown { 78795b482a8SLen Brown struct acpi_table_desc *tables; 7882bc198c1SLv Zheng u32 table_count; 78995b482a8SLen Brown 79095b482a8SLen Brown ACPI_FUNCTION_TRACE(tb_resize_root_table_list); 79195b482a8SLen Brown 79295b482a8SLen Brown /* allow_resize flag is a parameter to acpi_initialize_tables */ 79395b482a8SLen Brown 79495b482a8SLen Brown if (!(acpi_gbl_root_table_list.flags & ACPI_ROOT_ALLOW_RESIZE)) { 79595b482a8SLen Brown ACPI_ERROR((AE_INFO, 79695b482a8SLen Brown "Resize of Root Table Array is not allowed")); 79795b482a8SLen Brown return_ACPI_STATUS(AE_SUPPORT); 79895b482a8SLen Brown } 79995b482a8SLen Brown 80095b482a8SLen Brown /* Increase the Table Array size */ 80195b482a8SLen Brown 8022bc198c1SLv Zheng if (acpi_gbl_root_table_list.flags & ACPI_ROOT_ORIGIN_ALLOCATED) { 8032bc198c1SLv Zheng table_count = acpi_gbl_root_table_list.max_table_count; 8042bc198c1SLv Zheng } else { 8052bc198c1SLv Zheng table_count = acpi_gbl_root_table_list.current_table_count; 8062bc198c1SLv Zheng } 8072bc198c1SLv Zheng 8082bc198c1SLv Zheng tables = ACPI_ALLOCATE_ZEROED(((acpi_size) table_count + 809ec41f193SBob Moore ACPI_ROOT_TABLE_SIZE_INCREMENT) * 810ec41f193SBob Moore sizeof(struct acpi_table_desc)); 81195b482a8SLen Brown if (!tables) { 81295b482a8SLen Brown ACPI_ERROR((AE_INFO, 81395b482a8SLen Brown "Could not allocate new root table array")); 81495b482a8SLen Brown return_ACPI_STATUS(AE_NO_MEMORY); 81595b482a8SLen Brown } 81695b482a8SLen Brown 81795b482a8SLen Brown /* Copy and free the previous table array */ 81895b482a8SLen Brown 81995b482a8SLen Brown if (acpi_gbl_root_table_list.tables) { 82095b482a8SLen Brown ACPI_MEMCPY(tables, acpi_gbl_root_table_list.tables, 8212bc198c1SLv Zheng (acpi_size) table_count * 8222bc198c1SLv Zheng sizeof(struct acpi_table_desc)); 82395b482a8SLen Brown 82495b482a8SLen Brown if (acpi_gbl_root_table_list.flags & ACPI_ROOT_ORIGIN_ALLOCATED) { 82595b482a8SLen Brown ACPI_FREE(acpi_gbl_root_table_list.tables); 82695b482a8SLen Brown } 82795b482a8SLen Brown } 82895b482a8SLen Brown 82995b482a8SLen Brown acpi_gbl_root_table_list.tables = tables; 8302bc198c1SLv Zheng acpi_gbl_root_table_list.max_table_count = 8312bc198c1SLv Zheng table_count + ACPI_ROOT_TABLE_SIZE_INCREMENT; 8322bc198c1SLv Zheng acpi_gbl_root_table_list.flags |= ACPI_ROOT_ORIGIN_ALLOCATED; 83395b482a8SLen Brown 83495b482a8SLen Brown return_ACPI_STATUS(AE_OK); 83595b482a8SLen Brown } 83695b482a8SLen Brown 83795b482a8SLen Brown /******************************************************************************* 83895b482a8SLen Brown * 839*86dfc6f3SLv Zheng * FUNCTION: acpi_tb_acquire_root_table_entry 840*86dfc6f3SLv Zheng * 841*86dfc6f3SLv Zheng * PARAMETERS: table_index - Where table index is returned 842*86dfc6f3SLv Zheng * 843*86dfc6f3SLv Zheng * RETURN: Status and table index. 844*86dfc6f3SLv Zheng * 845*86dfc6f3SLv Zheng * DESCRIPTION: Allocate a new ACPI table entry to the global table list 846*86dfc6f3SLv Zheng * 847*86dfc6f3SLv Zheng ******************************************************************************/ 848*86dfc6f3SLv Zheng 849*86dfc6f3SLv Zheng static acpi_status acpi_tb_acquire_root_table_entry(u32 *table_index) 850*86dfc6f3SLv Zheng { 851*86dfc6f3SLv Zheng acpi_status status; 852*86dfc6f3SLv Zheng 853*86dfc6f3SLv Zheng /* Ensure that there is room for the table in the Root Table List */ 854*86dfc6f3SLv Zheng 855*86dfc6f3SLv Zheng if (acpi_gbl_root_table_list.current_table_count >= 856*86dfc6f3SLv Zheng acpi_gbl_root_table_list.max_table_count) { 857*86dfc6f3SLv Zheng status = acpi_tb_resize_root_table_list(); 858*86dfc6f3SLv Zheng if (ACPI_FAILURE(status)) { 859*86dfc6f3SLv Zheng return (status); 860*86dfc6f3SLv Zheng } 861*86dfc6f3SLv Zheng } 862*86dfc6f3SLv Zheng 863*86dfc6f3SLv Zheng *table_index = acpi_gbl_root_table_list.current_table_count; 864*86dfc6f3SLv Zheng acpi_gbl_root_table_list.current_table_count++; 865*86dfc6f3SLv Zheng return (AE_OK); 866*86dfc6f3SLv Zheng } 867*86dfc6f3SLv Zheng 868*86dfc6f3SLv Zheng /******************************************************************************* 869*86dfc6f3SLv Zheng * 87095b482a8SLen Brown * FUNCTION: acpi_tb_store_table 87195b482a8SLen Brown * 872ba494beeSBob Moore * PARAMETERS: address - Table address 873ba494beeSBob Moore * table - Table header 874ba494beeSBob Moore * length - Table length 875ba494beeSBob Moore * flags - flags 87695b482a8SLen Brown * 87795b482a8SLen Brown * RETURN: Status and table index. 87895b482a8SLen Brown * 87995b482a8SLen Brown * DESCRIPTION: Add an ACPI table to the global table list 88095b482a8SLen Brown * 88195b482a8SLen Brown ******************************************************************************/ 88295b482a8SLen Brown 88395b482a8SLen Brown acpi_status 88495b482a8SLen Brown acpi_tb_store_table(acpi_physical_address address, 88595b482a8SLen Brown struct acpi_table_header * table, 88695b482a8SLen Brown u32 length, u8 flags, u32 *table_index) 88795b482a8SLen Brown { 888b9ee2043SBob Moore acpi_status status; 889*86dfc6f3SLv Zheng struct acpi_table_desc *table_desc; 89095b482a8SLen Brown 891*86dfc6f3SLv Zheng status = acpi_tb_acquire_root_table_entry(table_index); 89295b482a8SLen Brown if (ACPI_FAILURE(status)) { 89395b482a8SLen Brown return (status); 89495b482a8SLen Brown } 895b9ee2043SBob Moore 89695b482a8SLen Brown /* Initialize added table */ 89795b482a8SLen Brown 898*86dfc6f3SLv Zheng table_desc = &acpi_gbl_root_table_list.tables[*table_index]; 899*86dfc6f3SLv Zheng acpi_tb_install_table(table_desc, address, flags, table); 900*86dfc6f3SLv Zheng table_desc->pointer = table; 90195b482a8SLen Brown 902b9ee2043SBob Moore return (AE_OK); 90395b482a8SLen Brown } 90495b482a8SLen Brown 90595b482a8SLen Brown /******************************************************************************* 90695b482a8SLen Brown * 9077f9fc99cSLv Zheng * FUNCTION: acpi_tb_uninstall_table 90895b482a8SLen Brown * 9097f9fc99cSLv Zheng * PARAMETERS: table_desc - Table descriptor 91095b482a8SLen Brown * 91195b482a8SLen Brown * RETURN: None 91295b482a8SLen Brown * 91395b482a8SLen Brown * DESCRIPTION: Delete one internal ACPI table 91495b482a8SLen Brown * 91595b482a8SLen Brown ******************************************************************************/ 91695b482a8SLen Brown 9177f9fc99cSLv Zheng void acpi_tb_uninstall_table(struct acpi_table_desc *table_desc) 91895b482a8SLen Brown { 9195582982dSLv Zheng 9207f9fc99cSLv Zheng ACPI_FUNCTION_TRACE(tb_uninstall_table); 9215582982dSLv Zheng 9227f9fc99cSLv Zheng /* Table must be installed */ 9237f9fc99cSLv Zheng 9247f9fc99cSLv Zheng if (!table_desc->address) { 9257f9fc99cSLv Zheng return_VOID; 92695b482a8SLen Brown } 9275582982dSLv Zheng 9287f9fc99cSLv Zheng acpi_tb_invalidate_table(table_desc); 9291d1ea1b7SChao Guan 9307f9fc99cSLv Zheng if ((table_desc->flags & ACPI_TABLE_ORIGIN_MASK) == 9317f9fc99cSLv Zheng ACPI_TABLE_ORIGIN_ALLOCATED) { 9327f9fc99cSLv Zheng ACPI_FREE(ACPI_CAST_PTR(void, table_desc->address)); 9337f9fc99cSLv Zheng } 9341d1ea1b7SChao Guan 935dc156adfSLv Zheng table_desc->address = ACPI_PTR_TO_PHYSADDR(NULL); 936f7b004a1SBob Moore 9377f9fc99cSLv Zheng return_VOID; 93895b482a8SLen Brown } 93995b482a8SLen Brown 94095b482a8SLen Brown /******************************************************************************* 94195b482a8SLen Brown * 94295b482a8SLen Brown * FUNCTION: acpi_tb_terminate 94395b482a8SLen Brown * 94495b482a8SLen Brown * PARAMETERS: None 94595b482a8SLen Brown * 94695b482a8SLen Brown * RETURN: None 94795b482a8SLen Brown * 94895b482a8SLen Brown * DESCRIPTION: Delete all internal ACPI tables 94995b482a8SLen Brown * 95095b482a8SLen Brown ******************************************************************************/ 95195b482a8SLen Brown 95295b482a8SLen Brown void acpi_tb_terminate(void) 95395b482a8SLen Brown { 95495b482a8SLen Brown u32 i; 95595b482a8SLen Brown 95695b482a8SLen Brown ACPI_FUNCTION_TRACE(tb_terminate); 95795b482a8SLen Brown 95895b482a8SLen Brown (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); 95995b482a8SLen Brown 96095b482a8SLen Brown /* Delete the individual tables */ 96195b482a8SLen Brown 962b9ee2043SBob Moore for (i = 0; i < acpi_gbl_root_table_list.current_table_count; i++) { 9637f9fc99cSLv Zheng acpi_tb_uninstall_table(&acpi_gbl_root_table_list.tables[i]); 96495b482a8SLen Brown } 96595b482a8SLen Brown 96695b482a8SLen Brown /* 96795b482a8SLen Brown * Delete the root table array if allocated locally. Array cannot be 96895b482a8SLen Brown * mapped, so we don't need to check for that flag. 96995b482a8SLen Brown */ 97095b482a8SLen Brown if (acpi_gbl_root_table_list.flags & ACPI_ROOT_ORIGIN_ALLOCATED) { 97195b482a8SLen Brown ACPI_FREE(acpi_gbl_root_table_list.tables); 97295b482a8SLen Brown } 97395b482a8SLen Brown 97495b482a8SLen Brown acpi_gbl_root_table_list.tables = NULL; 97595b482a8SLen Brown acpi_gbl_root_table_list.flags = 0; 976b9ee2043SBob Moore acpi_gbl_root_table_list.current_table_count = 0; 97795b482a8SLen Brown 97895b482a8SLen Brown ACPI_DEBUG_PRINT((ACPI_DB_INFO, "ACPI Tables freed\n")); 97995b482a8SLen Brown (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); 98068aafc35SBob Moore 98168aafc35SBob Moore return_VOID; 98295b482a8SLen Brown } 98395b482a8SLen Brown 98495b482a8SLen Brown /******************************************************************************* 98595b482a8SLen Brown * 98695b482a8SLen Brown * FUNCTION: acpi_tb_delete_namespace_by_owner 98795b482a8SLen Brown * 98895b482a8SLen Brown * PARAMETERS: table_index - Table index 98995b482a8SLen Brown * 9908a335a23SBob Moore * RETURN: Status 99195b482a8SLen Brown * 99295b482a8SLen Brown * DESCRIPTION: Delete all namespace objects created when this table was loaded. 99395b482a8SLen Brown * 99495b482a8SLen Brown ******************************************************************************/ 99595b482a8SLen Brown 9968a335a23SBob Moore acpi_status acpi_tb_delete_namespace_by_owner(u32 table_index) 99795b482a8SLen Brown { 99895b482a8SLen Brown acpi_owner_id owner_id; 9998a335a23SBob Moore acpi_status status; 100095b482a8SLen Brown 10018a335a23SBob Moore ACPI_FUNCTION_TRACE(tb_delete_namespace_by_owner); 10028a335a23SBob Moore 10038a335a23SBob Moore status = acpi_ut_acquire_mutex(ACPI_MTX_TABLES); 10048a335a23SBob Moore if (ACPI_FAILURE(status)) { 10058a335a23SBob Moore return_ACPI_STATUS(status); 100695b482a8SLen Brown } 100795b482a8SLen Brown 1008b9ee2043SBob Moore if (table_index >= acpi_gbl_root_table_list.current_table_count) { 10098a335a23SBob Moore 10108a335a23SBob Moore /* The table index does not exist */ 10118a335a23SBob Moore 101295b482a8SLen Brown (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); 10138a335a23SBob Moore return_ACPI_STATUS(AE_NOT_EXIST); 10148a335a23SBob Moore } 10158a335a23SBob Moore 10168a335a23SBob Moore /* Get the owner ID for this table, used to delete namespace nodes */ 10178a335a23SBob Moore 10188a335a23SBob Moore owner_id = acpi_gbl_root_table_list.tables[table_index].owner_id; 10198a335a23SBob Moore (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); 10208a335a23SBob Moore 10218a335a23SBob Moore /* 10228a335a23SBob Moore * Need to acquire the namespace writer lock to prevent interference 10238a335a23SBob Moore * with any concurrent namespace walks. The interpreter must be 10248a335a23SBob Moore * released during the deletion since the acquisition of the deletion 10258a335a23SBob Moore * lock may block, and also since the execution of a namespace walk 10268a335a23SBob Moore * must be allowed to use the interpreter. 10278a335a23SBob Moore */ 1028e4c1ebfcSBob Moore (void)acpi_ut_release_mutex(ACPI_MTX_INTERPRETER); 10298a335a23SBob Moore status = acpi_ut_acquire_write_lock(&acpi_gbl_namespace_rw_lock); 10308a335a23SBob Moore 103195b482a8SLen Brown acpi_ns_delete_namespace_by_owner(owner_id); 10328a335a23SBob Moore if (ACPI_FAILURE(status)) { 10338a335a23SBob Moore return_ACPI_STATUS(status); 10348a335a23SBob Moore } 10358a335a23SBob Moore 10368a335a23SBob Moore acpi_ut_release_write_lock(&acpi_gbl_namespace_rw_lock); 10378a335a23SBob Moore 10388a335a23SBob Moore status = acpi_ut_acquire_mutex(ACPI_MTX_INTERPRETER); 10398a335a23SBob Moore return_ACPI_STATUS(status); 104095b482a8SLen Brown } 104195b482a8SLen Brown 104295b482a8SLen Brown /******************************************************************************* 104395b482a8SLen Brown * 104495b482a8SLen Brown * FUNCTION: acpi_tb_allocate_owner_id 104595b482a8SLen Brown * 104695b482a8SLen Brown * PARAMETERS: table_index - Table index 104795b482a8SLen Brown * 104895b482a8SLen Brown * RETURN: Status 104995b482a8SLen Brown * 105095b482a8SLen Brown * DESCRIPTION: Allocates owner_id in table_desc 105195b482a8SLen Brown * 105295b482a8SLen Brown ******************************************************************************/ 105395b482a8SLen Brown 105495b482a8SLen Brown acpi_status acpi_tb_allocate_owner_id(u32 table_index) 105595b482a8SLen Brown { 105695b482a8SLen Brown acpi_status status = AE_BAD_PARAMETER; 105795b482a8SLen Brown 105895b482a8SLen Brown ACPI_FUNCTION_TRACE(tb_allocate_owner_id); 105995b482a8SLen Brown 106095b482a8SLen Brown (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); 1061b9ee2043SBob Moore if (table_index < acpi_gbl_root_table_list.current_table_count) { 106295b482a8SLen Brown status = acpi_ut_allocate_owner_id 106395b482a8SLen Brown (&(acpi_gbl_root_table_list.tables[table_index].owner_id)); 106495b482a8SLen Brown } 106595b482a8SLen Brown 106695b482a8SLen Brown (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); 106795b482a8SLen Brown return_ACPI_STATUS(status); 106895b482a8SLen Brown } 106995b482a8SLen Brown 107095b482a8SLen Brown /******************************************************************************* 107195b482a8SLen Brown * 107295b482a8SLen Brown * FUNCTION: acpi_tb_release_owner_id 107395b482a8SLen Brown * 107495b482a8SLen Brown * PARAMETERS: table_index - Table index 107595b482a8SLen Brown * 107695b482a8SLen Brown * RETURN: Status 107795b482a8SLen Brown * 107895b482a8SLen Brown * DESCRIPTION: Releases owner_id in table_desc 107995b482a8SLen Brown * 108095b482a8SLen Brown ******************************************************************************/ 108195b482a8SLen Brown 108295b482a8SLen Brown acpi_status acpi_tb_release_owner_id(u32 table_index) 108395b482a8SLen Brown { 108495b482a8SLen Brown acpi_status status = AE_BAD_PARAMETER; 108595b482a8SLen Brown 108695b482a8SLen Brown ACPI_FUNCTION_TRACE(tb_release_owner_id); 108795b482a8SLen Brown 108895b482a8SLen Brown (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); 1089b9ee2043SBob Moore if (table_index < acpi_gbl_root_table_list.current_table_count) { 109095b482a8SLen Brown acpi_ut_release_owner_id(& 109195b482a8SLen Brown (acpi_gbl_root_table_list. 109295b482a8SLen Brown tables[table_index].owner_id)); 109395b482a8SLen Brown status = AE_OK; 109495b482a8SLen Brown } 109595b482a8SLen Brown 109695b482a8SLen Brown (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); 109795b482a8SLen Brown return_ACPI_STATUS(status); 109895b482a8SLen Brown } 109995b482a8SLen Brown 110095b482a8SLen Brown /******************************************************************************* 110195b482a8SLen Brown * 110295b482a8SLen Brown * FUNCTION: acpi_tb_get_owner_id 110395b482a8SLen Brown * 110495b482a8SLen Brown * PARAMETERS: table_index - Table index 110595b482a8SLen Brown * owner_id - Where the table owner_id is returned 110695b482a8SLen Brown * 110795b482a8SLen Brown * RETURN: Status 110895b482a8SLen Brown * 110995b482a8SLen Brown * DESCRIPTION: returns owner_id for the ACPI table 111095b482a8SLen Brown * 111195b482a8SLen Brown ******************************************************************************/ 111295b482a8SLen Brown 111395b482a8SLen Brown acpi_status acpi_tb_get_owner_id(u32 table_index, acpi_owner_id * owner_id) 111495b482a8SLen Brown { 111595b482a8SLen Brown acpi_status status = AE_BAD_PARAMETER; 111695b482a8SLen Brown 111795b482a8SLen Brown ACPI_FUNCTION_TRACE(tb_get_owner_id); 111895b482a8SLen Brown 111995b482a8SLen Brown (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); 1120b9ee2043SBob Moore if (table_index < acpi_gbl_root_table_list.current_table_count) { 112195b482a8SLen Brown *owner_id = 112295b482a8SLen Brown acpi_gbl_root_table_list.tables[table_index].owner_id; 112395b482a8SLen Brown status = AE_OK; 112495b482a8SLen Brown } 112595b482a8SLen Brown 112695b482a8SLen Brown (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); 112795b482a8SLen Brown return_ACPI_STATUS(status); 112895b482a8SLen Brown } 112995b482a8SLen Brown 113095b482a8SLen Brown /******************************************************************************* 113195b482a8SLen Brown * 113295b482a8SLen Brown * FUNCTION: acpi_tb_is_table_loaded 113395b482a8SLen Brown * 113495b482a8SLen Brown * PARAMETERS: table_index - Table index 113595b482a8SLen Brown * 113695b482a8SLen Brown * RETURN: Table Loaded Flag 113795b482a8SLen Brown * 113895b482a8SLen Brown ******************************************************************************/ 113995b482a8SLen Brown 114095b482a8SLen Brown u8 acpi_tb_is_table_loaded(u32 table_index) 114195b482a8SLen Brown { 114295b482a8SLen Brown u8 is_loaded = FALSE; 114395b482a8SLen Brown 114495b482a8SLen Brown (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); 1145b9ee2043SBob Moore if (table_index < acpi_gbl_root_table_list.current_table_count) { 114695b482a8SLen Brown is_loaded = (u8) 1147ec41f193SBob Moore (acpi_gbl_root_table_list.tables[table_index].flags & 1148ec41f193SBob Moore ACPI_TABLE_IS_LOADED); 114995b482a8SLen Brown } 115095b482a8SLen Brown 115195b482a8SLen Brown (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); 115295b482a8SLen Brown return (is_loaded); 115395b482a8SLen Brown } 115495b482a8SLen Brown 115595b482a8SLen Brown /******************************************************************************* 115695b482a8SLen Brown * 115795b482a8SLen Brown * FUNCTION: acpi_tb_set_table_loaded_flag 115895b482a8SLen Brown * 115995b482a8SLen Brown * PARAMETERS: table_index - Table index 116095b482a8SLen Brown * is_loaded - TRUE if table is loaded, FALSE otherwise 116195b482a8SLen Brown * 116295b482a8SLen Brown * RETURN: None 116395b482a8SLen Brown * 116495b482a8SLen Brown * DESCRIPTION: Sets the table loaded flag to either TRUE or FALSE. 116595b482a8SLen Brown * 116695b482a8SLen Brown ******************************************************************************/ 116795b482a8SLen Brown 116895b482a8SLen Brown void acpi_tb_set_table_loaded_flag(u32 table_index, u8 is_loaded) 116995b482a8SLen Brown { 117095b482a8SLen Brown 117195b482a8SLen Brown (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); 1172b9ee2043SBob Moore if (table_index < acpi_gbl_root_table_list.current_table_count) { 117395b482a8SLen Brown if (is_loaded) { 117495b482a8SLen Brown acpi_gbl_root_table_list.tables[table_index].flags |= 117595b482a8SLen Brown ACPI_TABLE_IS_LOADED; 117695b482a8SLen Brown } else { 117795b482a8SLen Brown acpi_gbl_root_table_list.tables[table_index].flags &= 117895b482a8SLen Brown ~ACPI_TABLE_IS_LOADED; 117995b482a8SLen Brown } 118095b482a8SLen Brown } 118195b482a8SLen Brown 118295b482a8SLen Brown (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); 118395b482a8SLen Brown } 1184