1 /****************************************************************************** 2 * 3 * Module Name: tbinstal - ACPI table installation and removal 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2017, Intel Corp. 9 * All rights reserved. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions, and the following disclaimer, 16 * without modification. 17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18 * substantially similar to the "NO WARRANTY" disclaimer below 19 * ("Disclaimer") and any redistribution must be conditioned upon 20 * including a substantially similar Disclaimer requirement for further 21 * binary redistribution. 22 * 3. Neither the names of the above-listed copyright holders nor the names 23 * of any contributors may be used to endorse or promote products derived 24 * from this software without specific prior written permission. 25 * 26 * Alternatively, this software may be distributed under the terms of the 27 * GNU General Public License ("GPL") version 2 as published by the Free 28 * Software Foundation. 29 * 30 * NO WARRANTY 31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41 * POSSIBILITY OF SUCH DAMAGES. 42 */ 43 44 #include <acpi/acpi.h> 45 #include "accommon.h" 46 #include "actables.h" 47 48 #define _COMPONENT ACPI_TABLES 49 ACPI_MODULE_NAME("tbinstal") 50 51 /******************************************************************************* 52 * 53 * FUNCTION: acpi_tb_install_table_with_override 54 * 55 * PARAMETERS: new_table_desc - New table descriptor to install 56 * override - Whether override should be performed 57 * table_index - Where the table index is returned 58 * 59 * RETURN: None 60 * 61 * DESCRIPTION: Install an ACPI table into the global data structure. The 62 * table override mechanism is called to allow the host 63 * OS to replace any table before it is installed in the root 64 * table array. 65 * 66 ******************************************************************************/ 67 void 68 acpi_tb_install_table_with_override(struct acpi_table_desc *new_table_desc, 69 u8 override, u32 *table_index) 70 { 71 u32 i; 72 acpi_status status; 73 74 status = acpi_tb_get_next_table_descriptor(&i, NULL); 75 if (ACPI_FAILURE(status)) { 76 return; 77 } 78 79 /* 80 * ACPI Table Override: 81 * 82 * Before we install the table, let the host OS override it with a new 83 * one if desired. Any table within the RSDT/XSDT can be replaced, 84 * including the DSDT which is pointed to by the FADT. 85 */ 86 if (override) { 87 acpi_tb_override_table(new_table_desc); 88 } 89 90 acpi_tb_init_table_descriptor(&acpi_gbl_root_table_list.tables[i], 91 new_table_desc->address, 92 new_table_desc->flags, 93 new_table_desc->pointer); 94 95 acpi_tb_print_table_header(new_table_desc->address, 96 new_table_desc->pointer); 97 98 /* This synchronizes acpi_gbl_dsdt_index */ 99 100 *table_index = i; 101 102 /* Set the global integer width (based upon revision of the DSDT) */ 103 104 if (i == acpi_gbl_dsdt_index) { 105 acpi_ut_set_integer_width(new_table_desc->pointer->revision); 106 } 107 } 108 109 /******************************************************************************* 110 * 111 * FUNCTION: acpi_tb_install_standard_table 112 * 113 * PARAMETERS: address - Address of the table (might be a virtual 114 * address depending on the table_flags) 115 * flags - Flags for the table 116 * reload - Whether reload should be performed 117 * override - Whether override should be performed 118 * table_index - Where the table index is returned 119 * 120 * RETURN: Status 121 * 122 * DESCRIPTION: This function is called to verify and install an ACPI table. 123 * When this function is called by "Load" or "LoadTable" opcodes, 124 * or by acpi_load_table() API, the "Reload" parameter is set. 125 * After sucessfully returning from this function, table is 126 * "INSTALLED" but not "VALIDATED". 127 * 128 ******************************************************************************/ 129 130 acpi_status 131 acpi_tb_install_standard_table(acpi_physical_address address, 132 u8 flags, 133 u8 reload, u8 override, u32 *table_index) 134 { 135 u32 i; 136 acpi_status status = AE_OK; 137 struct acpi_table_desc new_table_desc; 138 139 ACPI_FUNCTION_TRACE(tb_install_standard_table); 140 141 /* Acquire a temporary table descriptor for validation */ 142 143 status = acpi_tb_acquire_temp_table(&new_table_desc, address, flags); 144 if (ACPI_FAILURE(status)) { 145 ACPI_ERROR((AE_INFO, 146 "Could not acquire table length at %8.8X%8.8X", 147 ACPI_FORMAT_UINT64(address))); 148 return_ACPI_STATUS(status); 149 } 150 151 /* 152 * Optionally do not load any SSDTs from the RSDT/XSDT. This can 153 * be useful for debugging ACPI problems on some machines. 154 */ 155 if (!reload && 156 acpi_gbl_disable_ssdt_table_install && 157 ACPI_COMPARE_NAME(&new_table_desc.signature, ACPI_SIG_SSDT)) { 158 ACPI_INFO(("Ignoring installation of %4.4s at %8.8X%8.8X", 159 new_table_desc.signature.ascii, 160 ACPI_FORMAT_UINT64(address))); 161 goto release_and_exit; 162 } 163 164 /* Acquire the table lock */ 165 166 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); 167 168 /* Validate and verify a table before installation */ 169 170 status = acpi_tb_verify_temp_table(&new_table_desc, NULL, &i); 171 if (ACPI_FAILURE(status)) { 172 if (status == AE_CTRL_TERMINATE) { 173 /* 174 * Table was unloaded, allow it to be reloaded. 175 * As we are going to return AE_OK to the caller, we should 176 * take the responsibility of freeing the input descriptor. 177 * Refill the input descriptor to ensure 178 * acpi_tb_install_table_with_override() can be called again to 179 * indicate the re-installation. 180 */ 181 acpi_tb_uninstall_table(&new_table_desc); 182 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); 183 *table_index = i; 184 return_ACPI_STATUS(AE_OK); 185 } 186 goto unlock_and_exit; 187 } 188 189 /* Add the table to the global root table list */ 190 191 acpi_tb_install_table_with_override(&new_table_desc, override, 192 table_index); 193 194 /* Invoke table handler */ 195 196 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); 197 acpi_tb_notify_table(ACPI_TABLE_EVENT_INSTALL, new_table_desc.pointer); 198 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); 199 200 unlock_and_exit: 201 202 /* Release the table lock */ 203 204 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); 205 206 release_and_exit: 207 208 /* Release the temporary table descriptor */ 209 210 acpi_tb_release_temp_table(&new_table_desc); 211 return_ACPI_STATUS(status); 212 } 213 214 /******************************************************************************* 215 * 216 * FUNCTION: acpi_tb_override_table 217 * 218 * PARAMETERS: old_table_desc - Validated table descriptor to be 219 * overridden 220 * 221 * RETURN: None 222 * 223 * DESCRIPTION: Attempt table override by calling the OSL override functions. 224 * Note: If the table is overridden, then the entire new table 225 * is acquired and returned by this function. 226 * Before/after invocation, the table descriptor is in a state 227 * that is "VALIDATED". 228 * 229 ******************************************************************************/ 230 231 void acpi_tb_override_table(struct acpi_table_desc *old_table_desc) 232 { 233 acpi_status status; 234 char *override_type; 235 struct acpi_table_desc new_table_desc; 236 struct acpi_table_header *table; 237 acpi_physical_address address; 238 u32 length; 239 240 /* (1) Attempt logical override (returns a logical address) */ 241 242 status = acpi_os_table_override(old_table_desc->pointer, &table); 243 if (ACPI_SUCCESS(status) && table) { 244 acpi_tb_acquire_temp_table(&new_table_desc, 245 ACPI_PTR_TO_PHYSADDR(table), 246 ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL); 247 override_type = "Logical"; 248 goto finish_override; 249 } 250 251 /* (2) Attempt physical override (returns a physical address) */ 252 253 status = acpi_os_physical_table_override(old_table_desc->pointer, 254 &address, &length); 255 if (ACPI_SUCCESS(status) && address && length) { 256 acpi_tb_acquire_temp_table(&new_table_desc, address, 257 ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL); 258 override_type = "Physical"; 259 goto finish_override; 260 } 261 262 return; /* There was no override */ 263 264 finish_override: 265 266 /* 267 * Validate and verify a table before overriding, no nested table 268 * duplication check as it's too complicated and unnecessary. 269 */ 270 status = acpi_tb_verify_temp_table(&new_table_desc, NULL, NULL); 271 if (ACPI_FAILURE(status)) { 272 return; 273 } 274 275 ACPI_INFO(("%4.4s 0x%8.8X%8.8X" 276 " %s table override, new table: 0x%8.8X%8.8X", 277 old_table_desc->signature.ascii, 278 ACPI_FORMAT_UINT64(old_table_desc->address), 279 override_type, ACPI_FORMAT_UINT64(new_table_desc.address))); 280 281 /* We can now uninstall the original table */ 282 283 acpi_tb_uninstall_table(old_table_desc); 284 285 /* 286 * Replace the original table descriptor and keep its state as 287 * "VALIDATED". 288 */ 289 acpi_tb_init_table_descriptor(old_table_desc, new_table_desc.address, 290 new_table_desc.flags, 291 new_table_desc.pointer); 292 acpi_tb_validate_temp_table(old_table_desc); 293 294 /* Release the temporary table descriptor */ 295 296 acpi_tb_release_temp_table(&new_table_desc); 297 } 298 299 /******************************************************************************* 300 * 301 * FUNCTION: acpi_tb_uninstall_table 302 * 303 * PARAMETERS: table_desc - Table descriptor 304 * 305 * RETURN: None 306 * 307 * DESCRIPTION: Delete one internal ACPI table 308 * 309 ******************************************************************************/ 310 311 void acpi_tb_uninstall_table(struct acpi_table_desc *table_desc) 312 { 313 314 ACPI_FUNCTION_TRACE(tb_uninstall_table); 315 316 /* Table must be installed */ 317 318 if (!table_desc->address) { 319 return_VOID; 320 } 321 322 acpi_tb_invalidate_table(table_desc); 323 324 if ((table_desc->flags & ACPI_TABLE_ORIGIN_MASK) == 325 ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL) { 326 ACPI_FREE(ACPI_PHYSADDR_TO_PTR(table_desc->address)); 327 } 328 329 table_desc->address = ACPI_PTR_TO_PHYSADDR(NULL); 330 return_VOID; 331 } 332