1 /****************************************************************************** 2 * 3 * Module Name: tbinstal - ACPI table installation and removal 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2011, 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 "acnamesp.h" 47 #include "actables.h" 48 49 #define _COMPONENT ACPI_TABLES 50 ACPI_MODULE_NAME("tbinstal") 51 52 /****************************************************************************** 53 * 54 * FUNCTION: acpi_tb_verify_table 55 * 56 * PARAMETERS: table_desc - table 57 * 58 * RETURN: Status 59 * 60 * DESCRIPTION: this function is called to verify and map table 61 * 62 *****************************************************************************/ 63 acpi_status acpi_tb_verify_table(struct acpi_table_desc *table_desc) 64 { 65 acpi_status status = AE_OK; 66 67 ACPI_FUNCTION_TRACE(tb_verify_table); 68 69 /* Map the table if necessary */ 70 71 if (!table_desc->pointer) { 72 if ((table_desc->flags & ACPI_TABLE_ORIGIN_MASK) == 73 ACPI_TABLE_ORIGIN_MAPPED) { 74 table_desc->pointer = 75 acpi_os_map_memory(table_desc->address, 76 table_desc->length); 77 } 78 if (!table_desc->pointer) { 79 return_ACPI_STATUS(AE_NO_MEMORY); 80 } 81 } 82 83 /* FACS is the odd table, has no standard ACPI header and no checksum */ 84 85 if (!ACPI_COMPARE_NAME(&table_desc->signature, ACPI_SIG_FACS)) { 86 87 /* Always calculate checksum, ignore bad checksum if requested */ 88 89 status = 90 acpi_tb_verify_checksum(table_desc->pointer, 91 table_desc->length); 92 } 93 94 return_ACPI_STATUS(status); 95 } 96 97 /******************************************************************************* 98 * 99 * FUNCTION: acpi_tb_add_table 100 * 101 * PARAMETERS: table_desc - Table descriptor 102 * table_index - Where the table index is returned 103 * 104 * RETURN: Status 105 * 106 * DESCRIPTION: This function is called to add an ACPI table. It is used to 107 * dynamically load tables via the Load and load_table AML 108 * operators. 109 * 110 ******************************************************************************/ 111 112 acpi_status 113 acpi_tb_add_table(struct acpi_table_desc *table_desc, u32 *table_index) 114 { 115 u32 i; 116 acpi_status status = AE_OK; 117 struct acpi_table_header *override_table = NULL; 118 119 ACPI_FUNCTION_TRACE(tb_add_table); 120 121 if (!table_desc->pointer) { 122 status = acpi_tb_verify_table(table_desc); 123 if (ACPI_FAILURE(status) || !table_desc->pointer) { 124 return_ACPI_STATUS(status); 125 } 126 } 127 128 /* 129 * Originally, we checked the table signature for "SSDT" or "PSDT" here. 130 * Next, we added support for OEMx tables, signature "OEM". 131 * Valid tables were encountered with a null signature, so we've just 132 * given up on validating the signature, since it seems to be a waste 133 * of code. The original code was removed (05/2008). 134 */ 135 136 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); 137 138 /* Check if table is already registered */ 139 140 for (i = 0; i < acpi_gbl_root_table_list.current_table_count; ++i) { 141 if (!acpi_gbl_root_table_list.tables[i].pointer) { 142 status = 143 acpi_tb_verify_table(&acpi_gbl_root_table_list. 144 tables[i]); 145 if (ACPI_FAILURE(status) 146 || !acpi_gbl_root_table_list.tables[i].pointer) { 147 continue; 148 } 149 } 150 151 /* 152 * Check for a table match on the entire table length, 153 * not just the header. 154 */ 155 if (table_desc->length != 156 acpi_gbl_root_table_list.tables[i].length) { 157 continue; 158 } 159 160 if (ACPI_MEMCMP(table_desc->pointer, 161 acpi_gbl_root_table_list.tables[i].pointer, 162 acpi_gbl_root_table_list.tables[i].length)) { 163 continue; 164 } 165 166 /* 167 * Note: the current mechanism does not unregister a table if it is 168 * dynamically unloaded. The related namespace entries are deleted, 169 * but the table remains in the root table list. 170 * 171 * The assumption here is that the number of different tables that 172 * will be loaded is actually small, and there is minimal overhead 173 * in just keeping the table in case it is needed again. 174 * 175 * If this assumption changes in the future (perhaps on large 176 * machines with many table load/unload operations), tables will 177 * need to be unregistered when they are unloaded, and slots in the 178 * root table list should be reused when empty. 179 */ 180 181 /* 182 * Table is already registered. 183 * We can delete the table that was passed as a parameter. 184 */ 185 acpi_tb_delete_table(table_desc); 186 *table_index = i; 187 188 if (acpi_gbl_root_table_list.tables[i]. 189 flags & ACPI_TABLE_IS_LOADED) { 190 191 /* Table is still loaded, this is an error */ 192 193 status = AE_ALREADY_EXISTS; 194 goto release; 195 } else { 196 /* Table was unloaded, allow it to be reloaded */ 197 198 table_desc->pointer = 199 acpi_gbl_root_table_list.tables[i].pointer; 200 table_desc->address = 201 acpi_gbl_root_table_list.tables[i].address; 202 status = AE_OK; 203 goto print_header; 204 } 205 } 206 207 /* 208 * ACPI Table Override: 209 * Allow the host to override dynamically loaded tables. 210 */ 211 status = acpi_os_table_override(table_desc->pointer, &override_table); 212 if (ACPI_SUCCESS(status) && override_table) { 213 ACPI_INFO((AE_INFO, 214 "%4.4s @ 0x%p Table override, replaced with:", 215 table_desc->pointer->signature, 216 ACPI_CAST_PTR(void, table_desc->address))); 217 218 /* We can delete the table that was passed as a parameter */ 219 220 acpi_tb_delete_table(table_desc); 221 222 /* Setup descriptor for the new table */ 223 224 table_desc->address = ACPI_PTR_TO_PHYSADDR(override_table); 225 table_desc->pointer = override_table; 226 table_desc->length = override_table->length; 227 table_desc->flags = ACPI_TABLE_ORIGIN_OVERRIDE; 228 } 229 230 /* Add the table to the global root table list */ 231 232 status = acpi_tb_store_table(table_desc->address, table_desc->pointer, 233 table_desc->length, table_desc->flags, 234 table_index); 235 if (ACPI_FAILURE(status)) { 236 goto release; 237 } 238 239 print_header: 240 acpi_tb_print_table_header(table_desc->address, table_desc->pointer); 241 242 release: 243 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); 244 return_ACPI_STATUS(status); 245 } 246 247 /******************************************************************************* 248 * 249 * FUNCTION: acpi_tb_resize_root_table_list 250 * 251 * PARAMETERS: None 252 * 253 * RETURN: Status 254 * 255 * DESCRIPTION: Expand the size of global table array 256 * 257 ******************************************************************************/ 258 259 acpi_status acpi_tb_resize_root_table_list(void) 260 { 261 struct acpi_table_desc *tables; 262 263 ACPI_FUNCTION_TRACE(tb_resize_root_table_list); 264 265 /* allow_resize flag is a parameter to acpi_initialize_tables */ 266 267 if (!(acpi_gbl_root_table_list.flags & ACPI_ROOT_ALLOW_RESIZE)) { 268 ACPI_ERROR((AE_INFO, 269 "Resize of Root Table Array is not allowed")); 270 return_ACPI_STATUS(AE_SUPPORT); 271 } 272 273 /* Increase the Table Array size */ 274 275 tables = ACPI_ALLOCATE_ZEROED(((acpi_size) acpi_gbl_root_table_list. 276 max_table_count + 277 ACPI_ROOT_TABLE_SIZE_INCREMENT) * 278 sizeof(struct acpi_table_desc)); 279 if (!tables) { 280 ACPI_ERROR((AE_INFO, 281 "Could not allocate new root table array")); 282 return_ACPI_STATUS(AE_NO_MEMORY); 283 } 284 285 /* Copy and free the previous table array */ 286 287 if (acpi_gbl_root_table_list.tables) { 288 ACPI_MEMCPY(tables, acpi_gbl_root_table_list.tables, 289 (acpi_size) acpi_gbl_root_table_list. 290 max_table_count * sizeof(struct acpi_table_desc)); 291 292 if (acpi_gbl_root_table_list.flags & ACPI_ROOT_ORIGIN_ALLOCATED) { 293 ACPI_FREE(acpi_gbl_root_table_list.tables); 294 } 295 } 296 297 acpi_gbl_root_table_list.tables = tables; 298 acpi_gbl_root_table_list.max_table_count += 299 ACPI_ROOT_TABLE_SIZE_INCREMENT; 300 acpi_gbl_root_table_list.flags |= (u8)ACPI_ROOT_ORIGIN_ALLOCATED; 301 302 return_ACPI_STATUS(AE_OK); 303 } 304 305 /******************************************************************************* 306 * 307 * FUNCTION: acpi_tb_store_table 308 * 309 * PARAMETERS: Address - Table address 310 * Table - Table header 311 * Length - Table length 312 * Flags - flags 313 * 314 * RETURN: Status and table index. 315 * 316 * DESCRIPTION: Add an ACPI table to the global table list 317 * 318 ******************************************************************************/ 319 320 acpi_status 321 acpi_tb_store_table(acpi_physical_address address, 322 struct acpi_table_header *table, 323 u32 length, u8 flags, u32 *table_index) 324 { 325 acpi_status status; 326 struct acpi_table_desc *new_table; 327 328 /* Ensure that there is room for the table in the Root Table List */ 329 330 if (acpi_gbl_root_table_list.current_table_count >= 331 acpi_gbl_root_table_list.max_table_count) { 332 status = acpi_tb_resize_root_table_list(); 333 if (ACPI_FAILURE(status)) { 334 return (status); 335 } 336 } 337 338 new_table = 339 &acpi_gbl_root_table_list.tables[acpi_gbl_root_table_list. 340 current_table_count]; 341 342 /* Initialize added table */ 343 344 new_table->address = address; 345 new_table->pointer = table; 346 new_table->length = length; 347 new_table->owner_id = 0; 348 new_table->flags = flags; 349 350 ACPI_MOVE_32_TO_32(&new_table->signature, table->signature); 351 352 *table_index = acpi_gbl_root_table_list.current_table_count; 353 acpi_gbl_root_table_list.current_table_count++; 354 return (AE_OK); 355 } 356 357 /******************************************************************************* 358 * 359 * FUNCTION: acpi_tb_delete_table 360 * 361 * PARAMETERS: table_index - Table index 362 * 363 * RETURN: None 364 * 365 * DESCRIPTION: Delete one internal ACPI table 366 * 367 ******************************************************************************/ 368 369 void acpi_tb_delete_table(struct acpi_table_desc *table_desc) 370 { 371 /* Table must be mapped or allocated */ 372 if (!table_desc->pointer) { 373 return; 374 } 375 switch (table_desc->flags & ACPI_TABLE_ORIGIN_MASK) { 376 case ACPI_TABLE_ORIGIN_MAPPED: 377 acpi_os_unmap_memory(table_desc->pointer, table_desc->length); 378 break; 379 case ACPI_TABLE_ORIGIN_ALLOCATED: 380 ACPI_FREE(table_desc->pointer); 381 break; 382 default:; 383 } 384 385 table_desc->pointer = NULL; 386 } 387 388 /******************************************************************************* 389 * 390 * FUNCTION: acpi_tb_terminate 391 * 392 * PARAMETERS: None 393 * 394 * RETURN: None 395 * 396 * DESCRIPTION: Delete all internal ACPI tables 397 * 398 ******************************************************************************/ 399 400 void acpi_tb_terminate(void) 401 { 402 u32 i; 403 404 ACPI_FUNCTION_TRACE(tb_terminate); 405 406 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); 407 408 /* Delete the individual tables */ 409 410 for (i = 0; i < acpi_gbl_root_table_list.current_table_count; i++) { 411 acpi_tb_delete_table(&acpi_gbl_root_table_list.tables[i]); 412 } 413 414 /* 415 * Delete the root table array if allocated locally. Array cannot be 416 * mapped, so we don't need to check for that flag. 417 */ 418 if (acpi_gbl_root_table_list.flags & ACPI_ROOT_ORIGIN_ALLOCATED) { 419 ACPI_FREE(acpi_gbl_root_table_list.tables); 420 } 421 422 acpi_gbl_root_table_list.tables = NULL; 423 acpi_gbl_root_table_list.flags = 0; 424 acpi_gbl_root_table_list.current_table_count = 0; 425 426 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "ACPI Tables freed\n")); 427 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); 428 } 429 430 /******************************************************************************* 431 * 432 * FUNCTION: acpi_tb_delete_namespace_by_owner 433 * 434 * PARAMETERS: table_index - Table index 435 * 436 * RETURN: Status 437 * 438 * DESCRIPTION: Delete all namespace objects created when this table was loaded. 439 * 440 ******************************************************************************/ 441 442 acpi_status acpi_tb_delete_namespace_by_owner(u32 table_index) 443 { 444 acpi_owner_id owner_id; 445 acpi_status status; 446 447 ACPI_FUNCTION_TRACE(tb_delete_namespace_by_owner); 448 449 status = acpi_ut_acquire_mutex(ACPI_MTX_TABLES); 450 if (ACPI_FAILURE(status)) { 451 return_ACPI_STATUS(status); 452 } 453 454 if (table_index >= acpi_gbl_root_table_list.current_table_count) { 455 456 /* The table index does not exist */ 457 458 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); 459 return_ACPI_STATUS(AE_NOT_EXIST); 460 } 461 462 /* Get the owner ID for this table, used to delete namespace nodes */ 463 464 owner_id = acpi_gbl_root_table_list.tables[table_index].owner_id; 465 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); 466 467 /* 468 * Need to acquire the namespace writer lock to prevent interference 469 * with any concurrent namespace walks. The interpreter must be 470 * released during the deletion since the acquisition of the deletion 471 * lock may block, and also since the execution of a namespace walk 472 * must be allowed to use the interpreter. 473 */ 474 (void)acpi_ut_release_mutex(ACPI_MTX_INTERPRETER); 475 status = acpi_ut_acquire_write_lock(&acpi_gbl_namespace_rw_lock); 476 477 acpi_ns_delete_namespace_by_owner(owner_id); 478 if (ACPI_FAILURE(status)) { 479 return_ACPI_STATUS(status); 480 } 481 482 acpi_ut_release_write_lock(&acpi_gbl_namespace_rw_lock); 483 484 status = acpi_ut_acquire_mutex(ACPI_MTX_INTERPRETER); 485 return_ACPI_STATUS(status); 486 } 487 488 /******************************************************************************* 489 * 490 * FUNCTION: acpi_tb_allocate_owner_id 491 * 492 * PARAMETERS: table_index - Table index 493 * 494 * RETURN: Status 495 * 496 * DESCRIPTION: Allocates owner_id in table_desc 497 * 498 ******************************************************************************/ 499 500 acpi_status acpi_tb_allocate_owner_id(u32 table_index) 501 { 502 acpi_status status = AE_BAD_PARAMETER; 503 504 ACPI_FUNCTION_TRACE(tb_allocate_owner_id); 505 506 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); 507 if (table_index < acpi_gbl_root_table_list.current_table_count) { 508 status = acpi_ut_allocate_owner_id 509 (&(acpi_gbl_root_table_list.tables[table_index].owner_id)); 510 } 511 512 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); 513 return_ACPI_STATUS(status); 514 } 515 516 /******************************************************************************* 517 * 518 * FUNCTION: acpi_tb_release_owner_id 519 * 520 * PARAMETERS: table_index - Table index 521 * 522 * RETURN: Status 523 * 524 * DESCRIPTION: Releases owner_id in table_desc 525 * 526 ******************************************************************************/ 527 528 acpi_status acpi_tb_release_owner_id(u32 table_index) 529 { 530 acpi_status status = AE_BAD_PARAMETER; 531 532 ACPI_FUNCTION_TRACE(tb_release_owner_id); 533 534 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); 535 if (table_index < acpi_gbl_root_table_list.current_table_count) { 536 acpi_ut_release_owner_id(& 537 (acpi_gbl_root_table_list. 538 tables[table_index].owner_id)); 539 status = AE_OK; 540 } 541 542 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); 543 return_ACPI_STATUS(status); 544 } 545 546 /******************************************************************************* 547 * 548 * FUNCTION: acpi_tb_get_owner_id 549 * 550 * PARAMETERS: table_index - Table index 551 * owner_id - Where the table owner_id is returned 552 * 553 * RETURN: Status 554 * 555 * DESCRIPTION: returns owner_id for the ACPI table 556 * 557 ******************************************************************************/ 558 559 acpi_status acpi_tb_get_owner_id(u32 table_index, acpi_owner_id *owner_id) 560 { 561 acpi_status status = AE_BAD_PARAMETER; 562 563 ACPI_FUNCTION_TRACE(tb_get_owner_id); 564 565 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); 566 if (table_index < acpi_gbl_root_table_list.current_table_count) { 567 *owner_id = 568 acpi_gbl_root_table_list.tables[table_index].owner_id; 569 status = AE_OK; 570 } 571 572 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); 573 return_ACPI_STATUS(status); 574 } 575 576 /******************************************************************************* 577 * 578 * FUNCTION: acpi_tb_is_table_loaded 579 * 580 * PARAMETERS: table_index - Table index 581 * 582 * RETURN: Table Loaded Flag 583 * 584 ******************************************************************************/ 585 586 u8 acpi_tb_is_table_loaded(u32 table_index) 587 { 588 u8 is_loaded = FALSE; 589 590 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); 591 if (table_index < acpi_gbl_root_table_list.current_table_count) { 592 is_loaded = (u8) 593 (acpi_gbl_root_table_list.tables[table_index].flags & 594 ACPI_TABLE_IS_LOADED); 595 } 596 597 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); 598 return (is_loaded); 599 } 600 601 /******************************************************************************* 602 * 603 * FUNCTION: acpi_tb_set_table_loaded_flag 604 * 605 * PARAMETERS: table_index - Table index 606 * is_loaded - TRUE if table is loaded, FALSE otherwise 607 * 608 * RETURN: None 609 * 610 * DESCRIPTION: Sets the table loaded flag to either TRUE or FALSE. 611 * 612 ******************************************************************************/ 613 614 void acpi_tb_set_table_loaded_flag(u32 table_index, u8 is_loaded) 615 { 616 617 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); 618 if (table_index < acpi_gbl_root_table_list.current_table_count) { 619 if (is_loaded) { 620 acpi_gbl_root_table_list.tables[table_index].flags |= 621 ACPI_TABLE_IS_LOADED; 622 } else { 623 acpi_gbl_root_table_list.tables[table_index].flags &= 624 ~ACPI_TABLE_IS_LOADED; 625 } 626 } 627 628 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); 629 } 630