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 54*ed6f1d44SBob Moore acpi_tb_acquire_temp_table(struct acpi_table_desc *table_desc, 5586dfc6f3SLv Zheng acpi_physical_address address, u8 flags); 5686dfc6f3SLv Zheng 57*ed6f1d44SBob Moore static void acpi_tb_release_temp_table(struct acpi_table_desc *table_desc); 5886dfc6f3SLv Zheng 59*ed6f1d44SBob Moore static acpi_status acpi_tb_get_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 * 76*ed6f1d44SBob Moore * DESCRIPTION: Acquire an ACPI table. It can be used for tables not 77*ed6f1d44SBob Moore * maintained in the 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) { 89*ed6f1d44SBob Moore case ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL: 90dc156adfSLv Zheng 917f9fc99cSLv Zheng table = 927f9fc99cSLv Zheng acpi_os_map_memory(table_desc->address, table_desc->length); 93dc156adfSLv Zheng break; 94dc156adfSLv Zheng 95*ed6f1d44SBob Moore case ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL: 96*ed6f1d44SBob Moore case ACPI_TABLE_ORIGIN_EXTERNAL_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 return (AE_OK); 1207f9fc99cSLv Zheng } 1217f9fc99cSLv Zheng 1227f9fc99cSLv Zheng /******************************************************************************* 1237f9fc99cSLv Zheng * 1247f9fc99cSLv Zheng * FUNCTION: acpi_tb_release_table 1257f9fc99cSLv Zheng * 1267f9fc99cSLv Zheng * PARAMETERS: table - Pointer for the table 1277f9fc99cSLv Zheng * table_length - Length for the table 1287f9fc99cSLv Zheng * table_flags - Allocation flags for the table 1297f9fc99cSLv Zheng * 1307f9fc99cSLv Zheng * RETURN: None 1317f9fc99cSLv Zheng * 132*ed6f1d44SBob Moore * DESCRIPTION: Release a table. The inverse of acpi_tb_acquire_table(). 1337f9fc99cSLv Zheng * 1347f9fc99cSLv Zheng ******************************************************************************/ 1357f9fc99cSLv Zheng 1367f9fc99cSLv Zheng void 1377f9fc99cSLv Zheng acpi_tb_release_table(struct acpi_table_header *table, 1387f9fc99cSLv Zheng u32 table_length, u8 table_flags) 1397f9fc99cSLv Zheng { 140*ed6f1d44SBob Moore 1417f9fc99cSLv Zheng switch (table_flags & ACPI_TABLE_ORIGIN_MASK) { 142*ed6f1d44SBob Moore case ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL: 1437f9fc99cSLv Zheng 1447f9fc99cSLv Zheng acpi_os_unmap_memory(table, table_length); 1457f9fc99cSLv Zheng break; 1467f9fc99cSLv Zheng 147*ed6f1d44SBob Moore case ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL: 148*ed6f1d44SBob Moore case ACPI_TABLE_ORIGIN_EXTERNAL_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 * 196*ed6f1d44SBob Moore * DESCRIPTION: Invalidate one internal ACPI table, this is the inverse 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 * 281*ed6f1d44SBob Moore * FUNCTION: acpi_tb_init_table_descriptor 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 * 290*ed6f1d44SBob Moore * DESCRIPTION: Initialize a new table descriptor 29186dfc6f3SLv Zheng * 29286dfc6f3SLv Zheng ******************************************************************************/ 29386dfc6f3SLv Zheng 29486dfc6f3SLv Zheng void 295*ed6f1d44SBob Moore acpi_tb_init_table_descriptor(struct acpi_table_desc *table_desc, 29686dfc6f3SLv Zheng acpi_physical_address address, 29786dfc6f3SLv Zheng u8 flags, struct acpi_table_header *table) 29886dfc6f3SLv Zheng { 299*ed6f1d44SBob Moore 30086dfc6f3SLv Zheng /* 301*ed6f1d44SBob Moore * Initialize the table descriptor. Set the pointer to NULL, since the 30286dfc6f3SLv Zheng * table is not fully mapped at this time. 30386dfc6f3SLv Zheng */ 30486dfc6f3SLv Zheng ACPI_MEMSET(table_desc, 0, sizeof(struct acpi_table_desc)); 30586dfc6f3SLv Zheng table_desc->address = address; 30686dfc6f3SLv Zheng table_desc->length = table->length; 30786dfc6f3SLv Zheng table_desc->flags = flags; 30886dfc6f3SLv Zheng ACPI_MOVE_32_TO_32(table_desc->signature.ascii, table->signature); 30986dfc6f3SLv Zheng } 31086dfc6f3SLv Zheng 31186dfc6f3SLv Zheng /******************************************************************************* 31286dfc6f3SLv Zheng * 313*ed6f1d44SBob Moore * FUNCTION: acpi_tb_acquire_temp_table 31486dfc6f3SLv Zheng * 31586dfc6f3SLv Zheng * PARAMETERS: table_desc - Table descriptor to be acquired 31686dfc6f3SLv Zheng * address - Address of the table 31786dfc6f3SLv Zheng * flags - Allocation flags of the table 31886dfc6f3SLv Zheng * 31986dfc6f3SLv Zheng * RETURN: Status 32086dfc6f3SLv Zheng * 32186dfc6f3SLv Zheng * DESCRIPTION: This function validates the table header to obtain the length 32286dfc6f3SLv Zheng * of a table and fills the table descriptor to make its state as 323*ed6f1d44SBob Moore * "INSTALLED". Such a table descriptor is only used for verified 32486dfc6f3SLv Zheng * installation. 32586dfc6f3SLv Zheng * 32686dfc6f3SLv Zheng ******************************************************************************/ 32786dfc6f3SLv Zheng 32886dfc6f3SLv Zheng static acpi_status 329*ed6f1d44SBob Moore acpi_tb_acquire_temp_table(struct acpi_table_desc *table_desc, 33086dfc6f3SLv Zheng acpi_physical_address address, u8 flags) 33186dfc6f3SLv Zheng { 33286dfc6f3SLv Zheng struct acpi_table_header *table_header; 33386dfc6f3SLv Zheng 33486dfc6f3SLv Zheng switch (flags & ACPI_TABLE_ORIGIN_MASK) { 335*ed6f1d44SBob Moore case ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL: 33686dfc6f3SLv Zheng 337*ed6f1d44SBob Moore /* Get the length of the full table from the header */ 33886dfc6f3SLv Zheng 33986dfc6f3SLv Zheng table_header = 34086dfc6f3SLv Zheng acpi_os_map_memory(address, 34186dfc6f3SLv Zheng sizeof(struct acpi_table_header)); 34286dfc6f3SLv Zheng if (!table_header) { 34386dfc6f3SLv Zheng return (AE_NO_MEMORY); 34486dfc6f3SLv Zheng } 345*ed6f1d44SBob Moore 346*ed6f1d44SBob Moore acpi_tb_init_table_descriptor(table_desc, address, flags, 347*ed6f1d44SBob Moore table_header); 34886dfc6f3SLv Zheng acpi_os_unmap_memory(table_header, 34986dfc6f3SLv Zheng sizeof(struct acpi_table_header)); 35086dfc6f3SLv Zheng return (AE_OK); 35186dfc6f3SLv Zheng 352*ed6f1d44SBob Moore case ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL: 353*ed6f1d44SBob Moore case ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL: 35486dfc6f3SLv Zheng 35586dfc6f3SLv Zheng table_header = ACPI_CAST_PTR(struct acpi_table_header, address); 35686dfc6f3SLv Zheng if (!table_header) { 35786dfc6f3SLv Zheng return (AE_NO_MEMORY); 35886dfc6f3SLv Zheng } 359*ed6f1d44SBob Moore 360*ed6f1d44SBob Moore acpi_tb_init_table_descriptor(table_desc, address, flags, 361*ed6f1d44SBob Moore table_header); 36286dfc6f3SLv Zheng return (AE_OK); 36386dfc6f3SLv Zheng 36486dfc6f3SLv Zheng default: 36586dfc6f3SLv Zheng 36686dfc6f3SLv Zheng break; 36786dfc6f3SLv Zheng } 36886dfc6f3SLv Zheng 36986dfc6f3SLv Zheng /* Table is not valid yet */ 37086dfc6f3SLv Zheng 37186dfc6f3SLv Zheng return (AE_NO_MEMORY); 37286dfc6f3SLv Zheng } 37386dfc6f3SLv Zheng 37486dfc6f3SLv Zheng /******************************************************************************* 37586dfc6f3SLv Zheng * 376*ed6f1d44SBob Moore * FUNCTION: acpi_tb_release_temp_table 37786dfc6f3SLv Zheng * 37886dfc6f3SLv Zheng * PARAMETERS: table_desc - Table descriptor to be released 37986dfc6f3SLv Zheng * 38086dfc6f3SLv Zheng * RETURN: Status 38186dfc6f3SLv Zheng * 382*ed6f1d44SBob Moore * DESCRIPTION: The inverse of acpi_tb_acquire_temp_table(). 38386dfc6f3SLv Zheng * 38486dfc6f3SLv Zheng ******************************************************************************/ 38586dfc6f3SLv Zheng 386*ed6f1d44SBob Moore static void acpi_tb_release_temp_table(struct acpi_table_desc *table_desc) 38786dfc6f3SLv Zheng { 388*ed6f1d44SBob Moore 38986dfc6f3SLv Zheng /* 39086dfc6f3SLv Zheng * Note that the .Address is maintained by the callers of 391*ed6f1d44SBob Moore * acpi_tb_acquire_temp_table(), thus do not invoke acpi_tb_uninstall_table() 39286dfc6f3SLv Zheng * where .Address will be freed. 39386dfc6f3SLv Zheng */ 39486dfc6f3SLv Zheng acpi_tb_invalidate_table(table_desc); 39586dfc6f3SLv Zheng } 39686dfc6f3SLv Zheng 39786dfc6f3SLv Zheng /******************************************************************************* 39886dfc6f3SLv Zheng * 399*ed6f1d44SBob Moore * FUNCTION: acpi_tb_install_table_with_override 40086dfc6f3SLv Zheng * 40186dfc6f3SLv Zheng * PARAMETERS: table_index - Index into root table array 40286dfc6f3SLv Zheng * new_table_desc - New table descriptor to install 403caf4a15cSLv Zheng * override - Whether override should be performed 40486dfc6f3SLv Zheng * 40586dfc6f3SLv Zheng * RETURN: None 40686dfc6f3SLv Zheng * 40786dfc6f3SLv Zheng * DESCRIPTION: Install an ACPI table into the global data structure. The 40886dfc6f3SLv Zheng * table override mechanism is called to allow the host 40986dfc6f3SLv Zheng * OS to replace any table before it is installed in the root 41086dfc6f3SLv Zheng * table array. 41186dfc6f3SLv Zheng * 41286dfc6f3SLv Zheng ******************************************************************************/ 41386dfc6f3SLv Zheng 41486dfc6f3SLv Zheng void 415*ed6f1d44SBob Moore acpi_tb_install_table_with_override(u32 table_index, 416caf4a15cSLv Zheng struct acpi_table_desc *new_table_desc, 417caf4a15cSLv Zheng u8 override) 41886dfc6f3SLv Zheng { 419*ed6f1d44SBob Moore 42086dfc6f3SLv Zheng if (table_index >= acpi_gbl_root_table_list.current_table_count) { 42186dfc6f3SLv Zheng return; 42286dfc6f3SLv Zheng } 42386dfc6f3SLv Zheng 42486dfc6f3SLv Zheng /* 42586dfc6f3SLv Zheng * ACPI Table Override: 42686dfc6f3SLv Zheng * 42786dfc6f3SLv Zheng * Before we install the table, let the host OS override it with a new 42886dfc6f3SLv Zheng * one if desired. Any table within the RSDT/XSDT can be replaced, 42986dfc6f3SLv Zheng * including the DSDT which is pointed to by the FADT. 43086dfc6f3SLv Zheng */ 431caf4a15cSLv Zheng if (override) { 43286dfc6f3SLv Zheng acpi_tb_override_table(new_table_desc); 433caf4a15cSLv Zheng } 43486dfc6f3SLv Zheng 435*ed6f1d44SBob Moore acpi_tb_init_table_descriptor(&acpi_gbl_root_table_list. 436*ed6f1d44SBob Moore tables[table_index], 437*ed6f1d44SBob Moore new_table_desc->address, 438*ed6f1d44SBob Moore new_table_desc->flags, 43986dfc6f3SLv Zheng new_table_desc->pointer); 44086dfc6f3SLv Zheng 44186dfc6f3SLv Zheng acpi_tb_print_table_header(new_table_desc->address, 44286dfc6f3SLv Zheng new_table_desc->pointer); 44386dfc6f3SLv Zheng 44486dfc6f3SLv Zheng /* Set the global integer width (based upon revision of the DSDT) */ 44586dfc6f3SLv Zheng 44686dfc6f3SLv Zheng if (table_index == ACPI_TABLE_INDEX_DSDT) { 44786dfc6f3SLv Zheng acpi_ut_set_integer_width(new_table_desc->pointer->revision); 44886dfc6f3SLv Zheng } 44986dfc6f3SLv Zheng } 45086dfc6f3SLv Zheng 45186dfc6f3SLv Zheng /******************************************************************************* 45286dfc6f3SLv Zheng * 45386dfc6f3SLv Zheng * FUNCTION: acpi_tb_install_fixed_table 45486dfc6f3SLv Zheng * 45586dfc6f3SLv Zheng * PARAMETERS: address - Physical address of DSDT or FACS 45686dfc6f3SLv Zheng * signature - Table signature, NULL if no need to 45786dfc6f3SLv Zheng * match 45886dfc6f3SLv Zheng * table_index - Index into root table array 45986dfc6f3SLv Zheng * 46086dfc6f3SLv Zheng * RETURN: Status 46186dfc6f3SLv Zheng * 46286dfc6f3SLv Zheng * DESCRIPTION: Install a fixed ACPI table (DSDT/FACS) into the global data 46386dfc6f3SLv Zheng * structure. 46495b482a8SLen Brown * 46595b482a8SLen Brown ******************************************************************************/ 46695b482a8SLen Brown 46795b482a8SLen Brown acpi_status 46886dfc6f3SLv Zheng acpi_tb_install_fixed_table(acpi_physical_address address, 46986dfc6f3SLv Zheng char *signature, u32 table_index) 47086dfc6f3SLv Zheng { 47186dfc6f3SLv Zheng struct acpi_table_desc new_table_desc; 47286dfc6f3SLv Zheng acpi_status status; 47386dfc6f3SLv Zheng 47486dfc6f3SLv Zheng ACPI_FUNCTION_TRACE(tb_install_fixed_table); 47586dfc6f3SLv Zheng 47686dfc6f3SLv Zheng if (!address) { 47786dfc6f3SLv Zheng ACPI_ERROR((AE_INFO, 47886dfc6f3SLv Zheng "Null physical address for ACPI table [%s]", 47986dfc6f3SLv Zheng signature)); 48086dfc6f3SLv Zheng return (AE_NO_MEMORY); 48186dfc6f3SLv Zheng } 48286dfc6f3SLv Zheng 48386dfc6f3SLv Zheng /* Fill a table descriptor for validation */ 48486dfc6f3SLv Zheng 485*ed6f1d44SBob Moore status = acpi_tb_acquire_temp_table(&new_table_desc, address, 486*ed6f1d44SBob Moore ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL); 48786dfc6f3SLv Zheng if (ACPI_FAILURE(status)) { 48886dfc6f3SLv Zheng ACPI_ERROR((AE_INFO, "Could not acquire table length at %p", 48986dfc6f3SLv Zheng ACPI_CAST_PTR(void, address))); 49086dfc6f3SLv Zheng return_ACPI_STATUS(status); 49186dfc6f3SLv Zheng } 49286dfc6f3SLv Zheng 49386dfc6f3SLv Zheng /* Validate and verify a table before installation */ 49486dfc6f3SLv Zheng 49586dfc6f3SLv Zheng status = acpi_tb_verify_table(&new_table_desc, signature); 49686dfc6f3SLv Zheng if (ACPI_FAILURE(status)) { 49786dfc6f3SLv Zheng goto release_and_exit; 49886dfc6f3SLv Zheng } 49986dfc6f3SLv Zheng 500*ed6f1d44SBob Moore acpi_tb_install_table_with_override(table_index, &new_table_desc, TRUE); 50186dfc6f3SLv Zheng 50286dfc6f3SLv Zheng release_and_exit: 50386dfc6f3SLv Zheng 504*ed6f1d44SBob Moore /* Release the temporary table descriptor */ 50586dfc6f3SLv Zheng 506*ed6f1d44SBob Moore acpi_tb_release_temp_table(&new_table_desc); 50786dfc6f3SLv Zheng return_ACPI_STATUS(status); 50886dfc6f3SLv Zheng } 50986dfc6f3SLv Zheng 51086dfc6f3SLv Zheng /******************************************************************************* 51186dfc6f3SLv Zheng * 51286dfc6f3SLv Zheng * FUNCTION: acpi_tb_is_equivalent_table 51386dfc6f3SLv Zheng * 51486dfc6f3SLv Zheng * PARAMETERS: table_desc - Table 1 descriptor to be compared 51586dfc6f3SLv Zheng * table_index - Index of table 2 to be compared 51686dfc6f3SLv Zheng * 51786dfc6f3SLv Zheng * RETURN: TRUE if 2 tables are equivalent 51886dfc6f3SLv Zheng * 51986dfc6f3SLv Zheng * DESCRIPTION: This function is called to compare a table with what have 52086dfc6f3SLv Zheng * already been installed in the root table list. 52186dfc6f3SLv Zheng * 52286dfc6f3SLv Zheng ******************************************************************************/ 52386dfc6f3SLv Zheng 52486dfc6f3SLv Zheng static u8 52586dfc6f3SLv Zheng acpi_tb_is_equivalent_table(struct acpi_table_desc *table_desc, u32 table_index) 52686dfc6f3SLv Zheng { 52786dfc6f3SLv Zheng acpi_status status = AE_OK; 52886dfc6f3SLv Zheng u8 is_equivalent; 52986dfc6f3SLv Zheng struct acpi_table_header *table; 53086dfc6f3SLv Zheng u32 table_length; 53186dfc6f3SLv Zheng u8 table_flags; 53286dfc6f3SLv Zheng 53386dfc6f3SLv Zheng status = 53486dfc6f3SLv Zheng acpi_tb_acquire_table(&acpi_gbl_root_table_list.tables[table_index], 53586dfc6f3SLv Zheng &table, &table_length, &table_flags); 53686dfc6f3SLv Zheng if (ACPI_FAILURE(status)) { 53786dfc6f3SLv Zheng return (FALSE); 53886dfc6f3SLv Zheng } 53986dfc6f3SLv Zheng 54086dfc6f3SLv Zheng /* 54186dfc6f3SLv Zheng * Check for a table match on the entire table length, 54286dfc6f3SLv Zheng * not just the header. 54386dfc6f3SLv Zheng */ 54486dfc6f3SLv Zheng is_equivalent = (u8)((table_desc->length != table_length || 54586dfc6f3SLv Zheng ACPI_MEMCMP(table_desc->pointer, table, 54686dfc6f3SLv Zheng table_length)) ? FALSE : TRUE); 54786dfc6f3SLv Zheng 54886dfc6f3SLv Zheng /* Release the acquired table */ 54986dfc6f3SLv Zheng 55086dfc6f3SLv Zheng acpi_tb_release_table(table, table_length, table_flags); 55186dfc6f3SLv Zheng return (is_equivalent); 55286dfc6f3SLv Zheng } 55386dfc6f3SLv Zheng 55486dfc6f3SLv Zheng /******************************************************************************* 55586dfc6f3SLv Zheng * 556*ed6f1d44SBob Moore * FUNCTION: acpi_tb_install_standard_table 55786dfc6f3SLv Zheng * 5588a216d7fSLv Zheng * PARAMETERS: address - Address of the table (might be a virtual 55986dfc6f3SLv Zheng * address depending on the table_flags) 56086dfc6f3SLv Zheng * flags - Flags for the table 56186dfc6f3SLv Zheng * reload - Whether reload should be performed 562caf4a15cSLv Zheng * override - Whether override should be performed 56386dfc6f3SLv Zheng * table_index - Where the table index is returned 56486dfc6f3SLv Zheng * 56586dfc6f3SLv Zheng * RETURN: Status 56686dfc6f3SLv Zheng * 56786dfc6f3SLv Zheng * DESCRIPTION: This function is called to install an ACPI table that is 568*ed6f1d44SBob Moore * neither DSDT nor FACS (a "standard" table.) 56986dfc6f3SLv Zheng * When this function is called by "Load" or "LoadTable" opcodes, 57086dfc6f3SLv Zheng * or by acpi_load_table() API, the "Reload" parameter is set. 57186dfc6f3SLv Zheng * After sucessfully returning from this function, table is 57286dfc6f3SLv Zheng * "INSTALLED" but not "VALIDATED". 57386dfc6f3SLv Zheng * 57486dfc6f3SLv Zheng ******************************************************************************/ 57586dfc6f3SLv Zheng 57686dfc6f3SLv Zheng acpi_status 577*ed6f1d44SBob Moore acpi_tb_install_standard_table(acpi_physical_address address, 578caf4a15cSLv Zheng u8 flags, 579caf4a15cSLv Zheng u8 reload, u8 override, u32 *table_index) 58095b482a8SLen Brown { 58195b482a8SLen Brown u32 i; 58295b482a8SLen Brown acpi_status status = AE_OK; 58386dfc6f3SLv Zheng struct acpi_table_desc new_table_desc; 58495b482a8SLen Brown 585*ed6f1d44SBob Moore ACPI_FUNCTION_TRACE(tb_install_standard_table); 58695b482a8SLen Brown 587*ed6f1d44SBob Moore /* Acquire a temporary table descriptor for validation */ 58886dfc6f3SLv Zheng 589*ed6f1d44SBob Moore status = acpi_tb_acquire_temp_table(&new_table_desc, address, flags); 59086dfc6f3SLv Zheng if (ACPI_FAILURE(status)) { 59186dfc6f3SLv Zheng ACPI_ERROR((AE_INFO, "Could not acquire table length at %p", 59286dfc6f3SLv Zheng ACPI_CAST_PTR(void, address))); 59395b482a8SLen Brown return_ACPI_STATUS(status); 59495b482a8SLen Brown } 59586dfc6f3SLv Zheng 596a94e88cdSLv Zheng /* 597a94e88cdSLv Zheng * Optionally do not load any SSDTs from the RSDT/XSDT. This can 598a94e88cdSLv Zheng * be useful for debugging ACPI problems on some machines. 599a94e88cdSLv Zheng */ 600*ed6f1d44SBob Moore if (!reload && 601*ed6f1d44SBob Moore acpi_gbl_disable_ssdt_table_install && 602a94e88cdSLv Zheng ACPI_COMPARE_NAME(&new_table_desc.signature, ACPI_SIG_SSDT)) { 603a94e88cdSLv Zheng ACPI_INFO((AE_INFO, "Ignoring installation of %4.4s at %p", 604a94e88cdSLv Zheng new_table_desc.signature.ascii, ACPI_CAST_PTR(void, 605a94e88cdSLv Zheng address))); 606a94e88cdSLv Zheng goto release_and_exit; 607a94e88cdSLv Zheng } 608a94e88cdSLv Zheng 60986dfc6f3SLv Zheng /* Validate and verify a table before installation */ 61086dfc6f3SLv Zheng 61186dfc6f3SLv Zheng status = acpi_tb_verify_table(&new_table_desc, NULL); 61286dfc6f3SLv Zheng if (ACPI_FAILURE(status)) { 61386dfc6f3SLv Zheng goto release_and_exit; 61495b482a8SLen Brown } 61595b482a8SLen Brown 61686dfc6f3SLv Zheng if (reload) { 61795b482a8SLen Brown /* 618c8cefe30SBob Moore * Validate the incoming table signature. 619c8cefe30SBob Moore * 620c8cefe30SBob Moore * 1) Originally, we checked the table signature for "SSDT" or "PSDT". 621c8cefe30SBob Moore * 2) We added support for OEMx tables, signature "OEM". 622c8cefe30SBob Moore * 3) Valid tables were encountered with a null signature, so we just 623c8cefe30SBob Moore * gave up on validating the signature, (05/2008). 624c8cefe30SBob Moore * 4) We encountered non-AML tables such as the MADT, which caused 625c8cefe30SBob Moore * interpreter errors and kernel faults. So now, we once again allow 626c8cefe30SBob Moore * only "SSDT", "OEMx", and now, also a null signature. (05/2011). 62795b482a8SLen Brown */ 62886dfc6f3SLv Zheng if ((new_table_desc.signature.ascii[0] != 0x00) && 62986dfc6f3SLv Zheng (!ACPI_COMPARE_NAME 63086dfc6f3SLv Zheng (&new_table_desc.signature, ACPI_SIG_SSDT)) 63186dfc6f3SLv Zheng && (ACPI_STRNCMP(new_table_desc.signature.ascii, "OEM", 3))) 63286dfc6f3SLv Zheng { 6333b3ea775SBob Moore ACPI_BIOS_ERROR((AE_INFO, 6343b3ea775SBob Moore "Table has invalid signature [%4.4s] (0x%8.8X), " 6353b3ea775SBob Moore "must be SSDT or OEMx", 63686dfc6f3SLv Zheng acpi_ut_valid_acpi_name(new_table_desc. 63786dfc6f3SLv Zheng signature. 63886dfc6f3SLv Zheng ascii) ? 63986dfc6f3SLv Zheng new_table_desc.signature. 64086dfc6f3SLv Zheng ascii : "????", 64186dfc6f3SLv Zheng new_table_desc.signature.integer)); 642c8cefe30SBob Moore 64386dfc6f3SLv Zheng status = AE_BAD_SIGNATURE; 64486dfc6f3SLv Zheng goto release_and_exit; 645c8cefe30SBob Moore } 64695b482a8SLen Brown 64795b482a8SLen Brown /* Check if table is already registered */ 64895b482a8SLen Brown 64986dfc6f3SLv Zheng for (i = 0; i < acpi_gbl_root_table_list.current_table_count; 65086dfc6f3SLv Zheng ++i) { 65195b482a8SLen Brown /* 65295b482a8SLen Brown * Check for a table match on the entire table length, 65395b482a8SLen Brown * not just the header. 65495b482a8SLen Brown */ 65586dfc6f3SLv Zheng if (!acpi_tb_is_equivalent_table(&new_table_desc, i)) { 65695b482a8SLen Brown continue; 65795b482a8SLen Brown } 65895b482a8SLen Brown 65995b482a8SLen Brown /* 66095b482a8SLen Brown * Note: the current mechanism does not unregister a table if it is 66195b482a8SLen Brown * dynamically unloaded. The related namespace entries are deleted, 66295b482a8SLen Brown * but the table remains in the root table list. 66395b482a8SLen Brown * 66495b482a8SLen Brown * The assumption here is that the number of different tables that 66595b482a8SLen Brown * will be loaded is actually small, and there is minimal overhead 66695b482a8SLen Brown * in just keeping the table in case it is needed again. 66795b482a8SLen Brown * 66895b482a8SLen Brown * If this assumption changes in the future (perhaps on large 66995b482a8SLen Brown * machines with many table load/unload operations), tables will 67095b482a8SLen Brown * need to be unregistered when they are unloaded, and slots in the 67195b482a8SLen Brown * root table list should be reused when empty. 67295b482a8SLen Brown */ 67395b482a8SLen Brown if (acpi_gbl_root_table_list.tables[i]. 67495b482a8SLen Brown flags & ACPI_TABLE_IS_LOADED) { 67595b482a8SLen Brown 67695b482a8SLen Brown /* Table is still loaded, this is an error */ 67795b482a8SLen Brown 67895b482a8SLen Brown status = AE_ALREADY_EXISTS; 67986dfc6f3SLv Zheng goto release_and_exit; 68095b482a8SLen Brown } else { 681d3ccaff8SBob Moore /* 68286dfc6f3SLv Zheng * Table was unloaded, allow it to be reloaded. 68386dfc6f3SLv Zheng * As we are going to return AE_OK to the caller, we should 68486dfc6f3SLv Zheng * take the responsibility of freeing the input descriptor. 68586dfc6f3SLv Zheng * Refill the input descriptor to ensure 686*ed6f1d44SBob Moore * acpi_tb_install_table_with_override() can be called again to 68786dfc6f3SLv Zheng * indicate the re-installation. 688d3ccaff8SBob Moore */ 68986dfc6f3SLv Zheng acpi_tb_uninstall_table(&new_table_desc); 69086dfc6f3SLv Zheng *table_index = i; 69186dfc6f3SLv Zheng (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); 69286dfc6f3SLv Zheng return_ACPI_STATUS(AE_OK); 69386dfc6f3SLv Zheng } 69486dfc6f3SLv Zheng } 6957f9fc99cSLv Zheng } 696d3ccaff8SBob Moore 69795b482a8SLen Brown /* Add the table to the global root table list */ 69895b482a8SLen Brown 699*ed6f1d44SBob Moore status = acpi_tb_get_root_table_entry(&i); 70095b482a8SLen Brown if (ACPI_FAILURE(status)) { 70186dfc6f3SLv Zheng goto release_and_exit; 70295b482a8SLen Brown } 703*ed6f1d44SBob Moore 70486dfc6f3SLv Zheng *table_index = i; 705*ed6f1d44SBob Moore acpi_tb_install_table_with_override(i, &new_table_desc, override); 70695b482a8SLen Brown 70786dfc6f3SLv Zheng release_and_exit: 70895b482a8SLen Brown 709*ed6f1d44SBob Moore /* Release the temporary table descriptor */ 71086dfc6f3SLv Zheng 711*ed6f1d44SBob Moore acpi_tb_release_temp_table(&new_table_desc); 71295b482a8SLen Brown return_ACPI_STATUS(status); 71395b482a8SLen Brown } 71495b482a8SLen Brown 71595b482a8SLen Brown /******************************************************************************* 71695b482a8SLen Brown * 7177f9fc99cSLv Zheng * FUNCTION: acpi_tb_override_table 718f7b004a1SBob Moore * 71986dfc6f3SLv Zheng * PARAMETERS: old_table_desc - Validated table descriptor to be 72086dfc6f3SLv Zheng * overridden 721f7b004a1SBob Moore * 72286dfc6f3SLv Zheng * RETURN: None 723f7b004a1SBob Moore * 724f7b004a1SBob Moore * DESCRIPTION: Attempt table override by calling the OSL override functions. 725f7b004a1SBob Moore * Note: If the table is overridden, then the entire new table 7267f9fc99cSLv Zheng * is acquired and returned by this function. 72786dfc6f3SLv Zheng * Before/after invocation, the table descriptor is in a state 72886dfc6f3SLv Zheng * that is "VALIDATED". 729f7b004a1SBob Moore * 730f7b004a1SBob Moore ******************************************************************************/ 731f7b004a1SBob Moore 73286dfc6f3SLv Zheng void acpi_tb_override_table(struct acpi_table_desc *old_table_desc) 733f7b004a1SBob Moore { 734f7b004a1SBob Moore acpi_status status; 735f7b004a1SBob Moore char *override_type; 7367f9fc99cSLv Zheng struct acpi_table_desc new_table_desc; 73786dfc6f3SLv Zheng struct acpi_table_header *table; 73886dfc6f3SLv Zheng acpi_physical_address address; 73986dfc6f3SLv Zheng u32 length; 740f7b004a1SBob Moore 741f7b004a1SBob Moore /* (1) Attempt logical override (returns a logical address) */ 742f7b004a1SBob Moore 74386dfc6f3SLv Zheng status = acpi_os_table_override(old_table_desc->pointer, &table); 74486dfc6f3SLv Zheng if (ACPI_SUCCESS(status) && table) { 745*ed6f1d44SBob Moore acpi_tb_acquire_temp_table(&new_table_desc, 74686dfc6f3SLv Zheng ACPI_PTR_TO_PHYSADDR(table), 747*ed6f1d44SBob Moore ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL); 748f7b004a1SBob Moore override_type = "Logical"; 749f7b004a1SBob Moore goto finish_override; 750f7b004a1SBob Moore } 751f7b004a1SBob Moore 752f7b004a1SBob Moore /* (2) Attempt physical override (returns a physical address) */ 753f7b004a1SBob Moore 75486dfc6f3SLv Zheng status = acpi_os_physical_table_override(old_table_desc->pointer, 75586dfc6f3SLv Zheng &address, &length); 75686dfc6f3SLv Zheng if (ACPI_SUCCESS(status) && address && length) { 757*ed6f1d44SBob Moore acpi_tb_acquire_temp_table(&new_table_desc, address, 758*ed6f1d44SBob Moore ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL); 759f7b004a1SBob Moore override_type = "Physical"; 760f7b004a1SBob Moore goto finish_override; 761f7b004a1SBob Moore } 762f7b004a1SBob Moore 76386dfc6f3SLv Zheng return; /* There was no override */ 764f7b004a1SBob Moore 765f7b004a1SBob Moore finish_override: 766f7b004a1SBob Moore 76786dfc6f3SLv Zheng /* Validate and verify a table before overriding */ 76886dfc6f3SLv Zheng 76986dfc6f3SLv Zheng status = acpi_tb_verify_table(&new_table_desc, NULL); 7707f9fc99cSLv Zheng if (ACPI_FAILURE(status)) { 77186dfc6f3SLv Zheng return; 7727f9fc99cSLv Zheng } 7737f9fc99cSLv Zheng 7742e19f8d0SBob Moore ACPI_INFO((AE_INFO, "%4.4s " ACPI_PRINTF_UINT 7752e19f8d0SBob Moore " %s table override, new table: " ACPI_PRINTF_UINT, 77686dfc6f3SLv Zheng old_table_desc->signature.ascii, 77786dfc6f3SLv Zheng ACPI_FORMAT_TO_UINT(old_table_desc->address), 7787f9fc99cSLv Zheng override_type, ACPI_FORMAT_TO_UINT(new_table_desc.address))); 779f7b004a1SBob Moore 78086dfc6f3SLv Zheng /* We can now uninstall the original table */ 781f7b004a1SBob Moore 78286dfc6f3SLv Zheng acpi_tb_uninstall_table(old_table_desc); 783f7b004a1SBob Moore 78486dfc6f3SLv Zheng /* 78586dfc6f3SLv Zheng * Replace the original table descriptor and keep its state as 78686dfc6f3SLv Zheng * "VALIDATED". 78786dfc6f3SLv Zheng */ 788*ed6f1d44SBob Moore acpi_tb_init_table_descriptor(old_table_desc, new_table_desc.address, 789*ed6f1d44SBob Moore new_table_desc.flags, 790*ed6f1d44SBob Moore new_table_desc.pointer); 79186dfc6f3SLv Zheng acpi_tb_validate_table(old_table_desc); 792f7b004a1SBob Moore 793*ed6f1d44SBob Moore /* Release the temporary table descriptor */ 794f7b004a1SBob Moore 795*ed6f1d44SBob Moore acpi_tb_release_temp_table(&new_table_desc); 796f7b004a1SBob Moore } 797f7b004a1SBob Moore 798f7b004a1SBob Moore /******************************************************************************* 799f7b004a1SBob Moore * 80095b482a8SLen Brown * FUNCTION: acpi_tb_resize_root_table_list 80195b482a8SLen Brown * 80295b482a8SLen Brown * PARAMETERS: None 80395b482a8SLen Brown * 80495b482a8SLen Brown * RETURN: Status 80595b482a8SLen Brown * 80695b482a8SLen Brown * DESCRIPTION: Expand the size of global table array 80795b482a8SLen Brown * 80895b482a8SLen Brown ******************************************************************************/ 80995b482a8SLen Brown 81095b482a8SLen Brown acpi_status acpi_tb_resize_root_table_list(void) 81195b482a8SLen Brown { 81295b482a8SLen Brown struct acpi_table_desc *tables; 8132bc198c1SLv Zheng u32 table_count; 81495b482a8SLen Brown 81595b482a8SLen Brown ACPI_FUNCTION_TRACE(tb_resize_root_table_list); 81695b482a8SLen Brown 81795b482a8SLen Brown /* allow_resize flag is a parameter to acpi_initialize_tables */ 81895b482a8SLen Brown 81995b482a8SLen Brown if (!(acpi_gbl_root_table_list.flags & ACPI_ROOT_ALLOW_RESIZE)) { 82095b482a8SLen Brown ACPI_ERROR((AE_INFO, 82195b482a8SLen Brown "Resize of Root Table Array is not allowed")); 82295b482a8SLen Brown return_ACPI_STATUS(AE_SUPPORT); 82395b482a8SLen Brown } 82495b482a8SLen Brown 82595b482a8SLen Brown /* Increase the Table Array size */ 82695b482a8SLen Brown 8272bc198c1SLv Zheng if (acpi_gbl_root_table_list.flags & ACPI_ROOT_ORIGIN_ALLOCATED) { 8282bc198c1SLv Zheng table_count = acpi_gbl_root_table_list.max_table_count; 8292bc198c1SLv Zheng } else { 8302bc198c1SLv Zheng table_count = acpi_gbl_root_table_list.current_table_count; 8312bc198c1SLv Zheng } 8322bc198c1SLv Zheng 8332bc198c1SLv Zheng tables = ACPI_ALLOCATE_ZEROED(((acpi_size) table_count + 834ec41f193SBob Moore ACPI_ROOT_TABLE_SIZE_INCREMENT) * 835ec41f193SBob Moore sizeof(struct acpi_table_desc)); 83695b482a8SLen Brown if (!tables) { 83795b482a8SLen Brown ACPI_ERROR((AE_INFO, 83895b482a8SLen Brown "Could not allocate new root table array")); 83995b482a8SLen Brown return_ACPI_STATUS(AE_NO_MEMORY); 84095b482a8SLen Brown } 84195b482a8SLen Brown 84295b482a8SLen Brown /* Copy and free the previous table array */ 84395b482a8SLen Brown 84495b482a8SLen Brown if (acpi_gbl_root_table_list.tables) { 84595b482a8SLen Brown ACPI_MEMCPY(tables, acpi_gbl_root_table_list.tables, 8462bc198c1SLv Zheng (acpi_size) table_count * 8472bc198c1SLv Zheng sizeof(struct acpi_table_desc)); 84895b482a8SLen Brown 84995b482a8SLen Brown if (acpi_gbl_root_table_list.flags & ACPI_ROOT_ORIGIN_ALLOCATED) { 85095b482a8SLen Brown ACPI_FREE(acpi_gbl_root_table_list.tables); 85195b482a8SLen Brown } 85295b482a8SLen Brown } 85395b482a8SLen Brown 85495b482a8SLen Brown acpi_gbl_root_table_list.tables = tables; 8552bc198c1SLv Zheng acpi_gbl_root_table_list.max_table_count = 8562bc198c1SLv Zheng table_count + ACPI_ROOT_TABLE_SIZE_INCREMENT; 8572bc198c1SLv Zheng acpi_gbl_root_table_list.flags |= ACPI_ROOT_ORIGIN_ALLOCATED; 85895b482a8SLen Brown 85995b482a8SLen Brown return_ACPI_STATUS(AE_OK); 86095b482a8SLen Brown } 86195b482a8SLen Brown 86295b482a8SLen Brown /******************************************************************************* 86395b482a8SLen Brown * 864*ed6f1d44SBob Moore * FUNCTION: acpi_tb_get_root_table_entry 86586dfc6f3SLv Zheng * 86686dfc6f3SLv Zheng * PARAMETERS: table_index - Where table index is returned 86786dfc6f3SLv Zheng * 86886dfc6f3SLv Zheng * RETURN: Status and table index. 86986dfc6f3SLv Zheng * 87086dfc6f3SLv Zheng * DESCRIPTION: Allocate a new ACPI table entry to the global table list 87186dfc6f3SLv Zheng * 87286dfc6f3SLv Zheng ******************************************************************************/ 87386dfc6f3SLv Zheng 874*ed6f1d44SBob Moore static acpi_status acpi_tb_get_root_table_entry(u32 *table_index) 87586dfc6f3SLv Zheng { 87686dfc6f3SLv Zheng acpi_status status; 87786dfc6f3SLv Zheng 87886dfc6f3SLv Zheng /* Ensure that there is room for the table in the Root Table List */ 87986dfc6f3SLv Zheng 88086dfc6f3SLv Zheng if (acpi_gbl_root_table_list.current_table_count >= 88186dfc6f3SLv Zheng acpi_gbl_root_table_list.max_table_count) { 88286dfc6f3SLv Zheng status = acpi_tb_resize_root_table_list(); 88386dfc6f3SLv Zheng if (ACPI_FAILURE(status)) { 88486dfc6f3SLv Zheng return (status); 88586dfc6f3SLv Zheng } 88686dfc6f3SLv Zheng } 88786dfc6f3SLv Zheng 88886dfc6f3SLv Zheng *table_index = acpi_gbl_root_table_list.current_table_count; 88986dfc6f3SLv Zheng acpi_gbl_root_table_list.current_table_count++; 89086dfc6f3SLv Zheng return (AE_OK); 89186dfc6f3SLv Zheng } 89286dfc6f3SLv Zheng 89386dfc6f3SLv Zheng /******************************************************************************* 89486dfc6f3SLv Zheng * 89595b482a8SLen Brown * FUNCTION: acpi_tb_store_table 89695b482a8SLen Brown * 897ba494beeSBob Moore * PARAMETERS: address - Table address 898ba494beeSBob Moore * table - Table header 899ba494beeSBob Moore * length - Table length 900*ed6f1d44SBob Moore * flags - Install flags 901*ed6f1d44SBob Moore * table_index - Where the table index is returned 90295b482a8SLen Brown * 90395b482a8SLen Brown * RETURN: Status and table index. 90495b482a8SLen Brown * 90595b482a8SLen Brown * DESCRIPTION: Add an ACPI table to the global table list 90695b482a8SLen Brown * 90795b482a8SLen Brown ******************************************************************************/ 90895b482a8SLen Brown 90995b482a8SLen Brown acpi_status 91095b482a8SLen Brown acpi_tb_store_table(acpi_physical_address address, 91195b482a8SLen Brown struct acpi_table_header * table, 91295b482a8SLen Brown u32 length, u8 flags, u32 *table_index) 91395b482a8SLen Brown { 914b9ee2043SBob Moore acpi_status status; 91586dfc6f3SLv Zheng struct acpi_table_desc *table_desc; 91695b482a8SLen Brown 917*ed6f1d44SBob Moore status = acpi_tb_get_root_table_entry(table_index); 91895b482a8SLen Brown if (ACPI_FAILURE(status)) { 91995b482a8SLen Brown return (status); 92095b482a8SLen Brown } 921b9ee2043SBob Moore 92295b482a8SLen Brown /* Initialize added table */ 92395b482a8SLen Brown 92486dfc6f3SLv Zheng table_desc = &acpi_gbl_root_table_list.tables[*table_index]; 925*ed6f1d44SBob Moore acpi_tb_init_table_descriptor(table_desc, address, flags, table); 92686dfc6f3SLv Zheng table_desc->pointer = table; 927b9ee2043SBob Moore return (AE_OK); 92895b482a8SLen Brown } 92995b482a8SLen Brown 93095b482a8SLen Brown /******************************************************************************* 93195b482a8SLen Brown * 9327f9fc99cSLv Zheng * FUNCTION: acpi_tb_uninstall_table 93395b482a8SLen Brown * 9347f9fc99cSLv Zheng * PARAMETERS: table_desc - Table descriptor 93595b482a8SLen Brown * 93695b482a8SLen Brown * RETURN: None 93795b482a8SLen Brown * 93895b482a8SLen Brown * DESCRIPTION: Delete one internal ACPI table 93995b482a8SLen Brown * 94095b482a8SLen Brown ******************************************************************************/ 94195b482a8SLen Brown 9427f9fc99cSLv Zheng void acpi_tb_uninstall_table(struct acpi_table_desc *table_desc) 94395b482a8SLen Brown { 9445582982dSLv Zheng 9457f9fc99cSLv Zheng ACPI_FUNCTION_TRACE(tb_uninstall_table); 9465582982dSLv Zheng 9477f9fc99cSLv Zheng /* Table must be installed */ 9487f9fc99cSLv Zheng 9497f9fc99cSLv Zheng if (!table_desc->address) { 9507f9fc99cSLv Zheng return_VOID; 95195b482a8SLen Brown } 9525582982dSLv Zheng 9537f9fc99cSLv Zheng acpi_tb_invalidate_table(table_desc); 9541d1ea1b7SChao Guan 9557f9fc99cSLv Zheng if ((table_desc->flags & ACPI_TABLE_ORIGIN_MASK) == 956*ed6f1d44SBob Moore ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL) { 9577f9fc99cSLv Zheng ACPI_FREE(ACPI_CAST_PTR(void, table_desc->address)); 9587f9fc99cSLv Zheng } 9591d1ea1b7SChao Guan 960dc156adfSLv Zheng table_desc->address = ACPI_PTR_TO_PHYSADDR(NULL); 9617f9fc99cSLv Zheng return_VOID; 96295b482a8SLen Brown } 96395b482a8SLen Brown 96495b482a8SLen Brown /******************************************************************************* 96595b482a8SLen Brown * 96695b482a8SLen Brown * FUNCTION: acpi_tb_terminate 96795b482a8SLen Brown * 96895b482a8SLen Brown * PARAMETERS: None 96995b482a8SLen Brown * 97095b482a8SLen Brown * RETURN: None 97195b482a8SLen Brown * 97295b482a8SLen Brown * DESCRIPTION: Delete all internal ACPI tables 97395b482a8SLen Brown * 97495b482a8SLen Brown ******************************************************************************/ 97595b482a8SLen Brown 97695b482a8SLen Brown void acpi_tb_terminate(void) 97795b482a8SLen Brown { 97895b482a8SLen Brown u32 i; 97995b482a8SLen Brown 98095b482a8SLen Brown ACPI_FUNCTION_TRACE(tb_terminate); 98195b482a8SLen Brown 98295b482a8SLen Brown (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); 98395b482a8SLen Brown 98495b482a8SLen Brown /* Delete the individual tables */ 98595b482a8SLen Brown 986b9ee2043SBob Moore for (i = 0; i < acpi_gbl_root_table_list.current_table_count; i++) { 9877f9fc99cSLv Zheng acpi_tb_uninstall_table(&acpi_gbl_root_table_list.tables[i]); 98895b482a8SLen Brown } 98995b482a8SLen Brown 99095b482a8SLen Brown /* 99195b482a8SLen Brown * Delete the root table array if allocated locally. Array cannot be 99295b482a8SLen Brown * mapped, so we don't need to check for that flag. 99395b482a8SLen Brown */ 99495b482a8SLen Brown if (acpi_gbl_root_table_list.flags & ACPI_ROOT_ORIGIN_ALLOCATED) { 99595b482a8SLen Brown ACPI_FREE(acpi_gbl_root_table_list.tables); 99695b482a8SLen Brown } 99795b482a8SLen Brown 99895b482a8SLen Brown acpi_gbl_root_table_list.tables = NULL; 99995b482a8SLen Brown acpi_gbl_root_table_list.flags = 0; 1000b9ee2043SBob Moore acpi_gbl_root_table_list.current_table_count = 0; 100195b482a8SLen Brown 100295b482a8SLen Brown ACPI_DEBUG_PRINT((ACPI_DB_INFO, "ACPI Tables freed\n")); 100368aafc35SBob Moore 1004*ed6f1d44SBob Moore (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); 100568aafc35SBob Moore return_VOID; 100695b482a8SLen Brown } 100795b482a8SLen Brown 100895b482a8SLen Brown /******************************************************************************* 100995b482a8SLen Brown * 101095b482a8SLen Brown * FUNCTION: acpi_tb_delete_namespace_by_owner 101195b482a8SLen Brown * 101295b482a8SLen Brown * PARAMETERS: table_index - Table index 101395b482a8SLen Brown * 10148a335a23SBob Moore * RETURN: Status 101595b482a8SLen Brown * 101695b482a8SLen Brown * DESCRIPTION: Delete all namespace objects created when this table was loaded. 101795b482a8SLen Brown * 101895b482a8SLen Brown ******************************************************************************/ 101995b482a8SLen Brown 10208a335a23SBob Moore acpi_status acpi_tb_delete_namespace_by_owner(u32 table_index) 102195b482a8SLen Brown { 102295b482a8SLen Brown acpi_owner_id owner_id; 10238a335a23SBob Moore acpi_status status; 102495b482a8SLen Brown 10258a335a23SBob Moore ACPI_FUNCTION_TRACE(tb_delete_namespace_by_owner); 10268a335a23SBob Moore 10278a335a23SBob Moore status = acpi_ut_acquire_mutex(ACPI_MTX_TABLES); 10288a335a23SBob Moore if (ACPI_FAILURE(status)) { 10298a335a23SBob Moore return_ACPI_STATUS(status); 103095b482a8SLen Brown } 103195b482a8SLen Brown 1032b9ee2043SBob Moore if (table_index >= acpi_gbl_root_table_list.current_table_count) { 10338a335a23SBob Moore 10348a335a23SBob Moore /* The table index does not exist */ 10358a335a23SBob Moore 103695b482a8SLen Brown (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); 10378a335a23SBob Moore return_ACPI_STATUS(AE_NOT_EXIST); 10388a335a23SBob Moore } 10398a335a23SBob Moore 10408a335a23SBob Moore /* Get the owner ID for this table, used to delete namespace nodes */ 10418a335a23SBob Moore 10428a335a23SBob Moore owner_id = acpi_gbl_root_table_list.tables[table_index].owner_id; 10438a335a23SBob Moore (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); 10448a335a23SBob Moore 10458a335a23SBob Moore /* 10468a335a23SBob Moore * Need to acquire the namespace writer lock to prevent interference 10478a335a23SBob Moore * with any concurrent namespace walks. The interpreter must be 10488a335a23SBob Moore * released during the deletion since the acquisition of the deletion 10498a335a23SBob Moore * lock may block, and also since the execution of a namespace walk 10508a335a23SBob Moore * must be allowed to use the interpreter. 10518a335a23SBob Moore */ 1052e4c1ebfcSBob Moore (void)acpi_ut_release_mutex(ACPI_MTX_INTERPRETER); 10538a335a23SBob Moore status = acpi_ut_acquire_write_lock(&acpi_gbl_namespace_rw_lock); 10548a335a23SBob Moore 105595b482a8SLen Brown acpi_ns_delete_namespace_by_owner(owner_id); 10568a335a23SBob Moore if (ACPI_FAILURE(status)) { 10578a335a23SBob Moore return_ACPI_STATUS(status); 10588a335a23SBob Moore } 10598a335a23SBob Moore 10608a335a23SBob Moore acpi_ut_release_write_lock(&acpi_gbl_namespace_rw_lock); 10618a335a23SBob Moore 10628a335a23SBob Moore status = acpi_ut_acquire_mutex(ACPI_MTX_INTERPRETER); 10638a335a23SBob Moore return_ACPI_STATUS(status); 106495b482a8SLen Brown } 106595b482a8SLen Brown 106695b482a8SLen Brown /******************************************************************************* 106795b482a8SLen Brown * 106895b482a8SLen Brown * FUNCTION: acpi_tb_allocate_owner_id 106995b482a8SLen Brown * 107095b482a8SLen Brown * PARAMETERS: table_index - Table index 107195b482a8SLen Brown * 107295b482a8SLen Brown * RETURN: Status 107395b482a8SLen Brown * 107495b482a8SLen Brown * DESCRIPTION: Allocates owner_id in table_desc 107595b482a8SLen Brown * 107695b482a8SLen Brown ******************************************************************************/ 107795b482a8SLen Brown 107895b482a8SLen Brown acpi_status acpi_tb_allocate_owner_id(u32 table_index) 107995b482a8SLen Brown { 108095b482a8SLen Brown acpi_status status = AE_BAD_PARAMETER; 108195b482a8SLen Brown 108295b482a8SLen Brown ACPI_FUNCTION_TRACE(tb_allocate_owner_id); 108395b482a8SLen Brown 108495b482a8SLen Brown (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); 1085b9ee2043SBob Moore if (table_index < acpi_gbl_root_table_list.current_table_count) { 1086*ed6f1d44SBob Moore status = 1087*ed6f1d44SBob Moore acpi_ut_allocate_owner_id(& 1088*ed6f1d44SBob Moore (acpi_gbl_root_table_list. 1089*ed6f1d44SBob Moore tables[table_index].owner_id)); 109095b482a8SLen Brown } 109195b482a8SLen Brown 109295b482a8SLen Brown (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); 109395b482a8SLen Brown return_ACPI_STATUS(status); 109495b482a8SLen Brown } 109595b482a8SLen Brown 109695b482a8SLen Brown /******************************************************************************* 109795b482a8SLen Brown * 109895b482a8SLen Brown * FUNCTION: acpi_tb_release_owner_id 109995b482a8SLen Brown * 110095b482a8SLen Brown * PARAMETERS: table_index - Table index 110195b482a8SLen Brown * 110295b482a8SLen Brown * RETURN: Status 110395b482a8SLen Brown * 110495b482a8SLen Brown * DESCRIPTION: Releases owner_id in table_desc 110595b482a8SLen Brown * 110695b482a8SLen Brown ******************************************************************************/ 110795b482a8SLen Brown 110895b482a8SLen Brown acpi_status acpi_tb_release_owner_id(u32 table_index) 110995b482a8SLen Brown { 111095b482a8SLen Brown acpi_status status = AE_BAD_PARAMETER; 111195b482a8SLen Brown 111295b482a8SLen Brown ACPI_FUNCTION_TRACE(tb_release_owner_id); 111395b482a8SLen Brown 111495b482a8SLen Brown (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); 1115b9ee2043SBob Moore if (table_index < acpi_gbl_root_table_list.current_table_count) { 111695b482a8SLen Brown acpi_ut_release_owner_id(& 111795b482a8SLen Brown (acpi_gbl_root_table_list. 111895b482a8SLen Brown tables[table_index].owner_id)); 111995b482a8SLen Brown status = AE_OK; 112095b482a8SLen Brown } 112195b482a8SLen Brown 112295b482a8SLen Brown (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); 112395b482a8SLen Brown return_ACPI_STATUS(status); 112495b482a8SLen Brown } 112595b482a8SLen Brown 112695b482a8SLen Brown /******************************************************************************* 112795b482a8SLen Brown * 112895b482a8SLen Brown * FUNCTION: acpi_tb_get_owner_id 112995b482a8SLen Brown * 113095b482a8SLen Brown * PARAMETERS: table_index - Table index 113195b482a8SLen Brown * owner_id - Where the table owner_id is returned 113295b482a8SLen Brown * 113395b482a8SLen Brown * RETURN: Status 113495b482a8SLen Brown * 113595b482a8SLen Brown * DESCRIPTION: returns owner_id for the ACPI table 113695b482a8SLen Brown * 113795b482a8SLen Brown ******************************************************************************/ 113895b482a8SLen Brown 113995b482a8SLen Brown acpi_status acpi_tb_get_owner_id(u32 table_index, acpi_owner_id * owner_id) 114095b482a8SLen Brown { 114195b482a8SLen Brown acpi_status status = AE_BAD_PARAMETER; 114295b482a8SLen Brown 114395b482a8SLen Brown ACPI_FUNCTION_TRACE(tb_get_owner_id); 114495b482a8SLen Brown 114595b482a8SLen Brown (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); 1146b9ee2043SBob Moore if (table_index < acpi_gbl_root_table_list.current_table_count) { 114795b482a8SLen Brown *owner_id = 114895b482a8SLen Brown acpi_gbl_root_table_list.tables[table_index].owner_id; 114995b482a8SLen Brown status = AE_OK; 115095b482a8SLen Brown } 115195b482a8SLen Brown 115295b482a8SLen Brown (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); 115395b482a8SLen Brown return_ACPI_STATUS(status); 115495b482a8SLen Brown } 115595b482a8SLen Brown 115695b482a8SLen Brown /******************************************************************************* 115795b482a8SLen Brown * 115895b482a8SLen Brown * FUNCTION: acpi_tb_is_table_loaded 115995b482a8SLen Brown * 1160*ed6f1d44SBob Moore * PARAMETERS: table_index - Index into the root table 116195b482a8SLen Brown * 116295b482a8SLen Brown * RETURN: Table Loaded Flag 116395b482a8SLen Brown * 116495b482a8SLen Brown ******************************************************************************/ 116595b482a8SLen Brown 116695b482a8SLen Brown u8 acpi_tb_is_table_loaded(u32 table_index) 116795b482a8SLen Brown { 116895b482a8SLen Brown u8 is_loaded = FALSE; 116995b482a8SLen Brown 117095b482a8SLen Brown (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); 1171b9ee2043SBob Moore if (table_index < acpi_gbl_root_table_list.current_table_count) { 117295b482a8SLen Brown is_loaded = (u8) 1173ec41f193SBob Moore (acpi_gbl_root_table_list.tables[table_index].flags & 1174ec41f193SBob Moore ACPI_TABLE_IS_LOADED); 117595b482a8SLen Brown } 117695b482a8SLen Brown 117795b482a8SLen Brown (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); 117895b482a8SLen Brown return (is_loaded); 117995b482a8SLen Brown } 118095b482a8SLen Brown 118195b482a8SLen Brown /******************************************************************************* 118295b482a8SLen Brown * 118395b482a8SLen Brown * FUNCTION: acpi_tb_set_table_loaded_flag 118495b482a8SLen Brown * 118595b482a8SLen Brown * PARAMETERS: table_index - Table index 118695b482a8SLen Brown * is_loaded - TRUE if table is loaded, FALSE otherwise 118795b482a8SLen Brown * 118895b482a8SLen Brown * RETURN: None 118995b482a8SLen Brown * 119095b482a8SLen Brown * DESCRIPTION: Sets the table loaded flag to either TRUE or FALSE. 119195b482a8SLen Brown * 119295b482a8SLen Brown ******************************************************************************/ 119395b482a8SLen Brown 119495b482a8SLen Brown void acpi_tb_set_table_loaded_flag(u32 table_index, u8 is_loaded) 119595b482a8SLen Brown { 119695b482a8SLen Brown 119795b482a8SLen Brown (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); 1198b9ee2043SBob Moore if (table_index < acpi_gbl_root_table_list.current_table_count) { 119995b482a8SLen Brown if (is_loaded) { 120095b482a8SLen Brown acpi_gbl_root_table_list.tables[table_index].flags |= 120195b482a8SLen Brown ACPI_TABLE_IS_LOADED; 120295b482a8SLen Brown } else { 120395b482a8SLen Brown acpi_gbl_root_table_list.tables[table_index].flags &= 120495b482a8SLen Brown ~ACPI_TABLE_IS_LOADED; 120595b482a8SLen Brown } 120695b482a8SLen Brown } 120795b482a8SLen Brown 120895b482a8SLen Brown (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); 120995b482a8SLen Brown } 1210