1 /****************************************************************************** 2 * 3 * Module Name: tbinstal - ACPI table installation and removal 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2008, 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.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 size + 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.size * 290 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.size += ACPI_ROOT_TABLE_SIZE_INCREMENT; 299 acpi_gbl_root_table_list.flags |= (u8) ACPI_ROOT_ORIGIN_ALLOCATED; 300 301 return_ACPI_STATUS(AE_OK); 302 } 303 304 /******************************************************************************* 305 * 306 * FUNCTION: acpi_tb_store_table 307 * 308 * PARAMETERS: Address - Table address 309 * Table - Table header 310 * Length - Table length 311 * Flags - flags 312 * 313 * RETURN: Status and table index. 314 * 315 * DESCRIPTION: Add an ACPI table to the global table list 316 * 317 ******************************************************************************/ 318 319 acpi_status 320 acpi_tb_store_table(acpi_physical_address address, 321 struct acpi_table_header *table, 322 u32 length, u8 flags, u32 *table_index) 323 { 324 acpi_status status = AE_OK; 325 326 /* Ensure that there is room for the table in the Root Table List */ 327 328 if (acpi_gbl_root_table_list.count >= acpi_gbl_root_table_list.size) { 329 status = acpi_tb_resize_root_table_list(); 330 if (ACPI_FAILURE(status)) { 331 return (status); 332 } 333 } 334 335 /* Initialize added table */ 336 337 acpi_gbl_root_table_list.tables[acpi_gbl_root_table_list.count]. 338 address = address; 339 acpi_gbl_root_table_list.tables[acpi_gbl_root_table_list.count]. 340 pointer = table; 341 acpi_gbl_root_table_list.tables[acpi_gbl_root_table_list.count].length = 342 length; 343 acpi_gbl_root_table_list.tables[acpi_gbl_root_table_list.count]. 344 owner_id = 0; 345 acpi_gbl_root_table_list.tables[acpi_gbl_root_table_list.count].flags = 346 flags; 347 348 ACPI_MOVE_32_TO_32(& 349 (acpi_gbl_root_table_list. 350 tables[acpi_gbl_root_table_list.count].signature), 351 table->signature); 352 353 *table_index = acpi_gbl_root_table_list.count; 354 acpi_gbl_root_table_list.count++; 355 return (status); 356 } 357 358 /******************************************************************************* 359 * 360 * FUNCTION: acpi_tb_delete_table 361 * 362 * PARAMETERS: table_index - Table index 363 * 364 * RETURN: None 365 * 366 * DESCRIPTION: Delete one internal ACPI table 367 * 368 ******************************************************************************/ 369 370 void acpi_tb_delete_table(struct acpi_table_desc *table_desc) 371 { 372 /* Table must be mapped or allocated */ 373 if (!table_desc->pointer) { 374 return; 375 } 376 switch (table_desc->flags & ACPI_TABLE_ORIGIN_MASK) { 377 case ACPI_TABLE_ORIGIN_MAPPED: 378 acpi_os_unmap_memory(table_desc->pointer, table_desc->length); 379 break; 380 case ACPI_TABLE_ORIGIN_ALLOCATED: 381 ACPI_FREE(table_desc->pointer); 382 break; 383 default:; 384 } 385 386 table_desc->pointer = NULL; 387 } 388 389 /******************************************************************************* 390 * 391 * FUNCTION: acpi_tb_terminate 392 * 393 * PARAMETERS: None 394 * 395 * RETURN: None 396 * 397 * DESCRIPTION: Delete all internal ACPI tables 398 * 399 ******************************************************************************/ 400 401 void acpi_tb_terminate(void) 402 { 403 u32 i; 404 405 ACPI_FUNCTION_TRACE(tb_terminate); 406 407 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); 408 409 /* Delete the individual tables */ 410 411 for (i = 0; i < acpi_gbl_root_table_list.count; ++i) { 412 acpi_tb_delete_table(&acpi_gbl_root_table_list.tables[i]); 413 } 414 415 /* 416 * Delete the root table array if allocated locally. Array cannot be 417 * mapped, so we don't need to check for that flag. 418 */ 419 if (acpi_gbl_root_table_list.flags & ACPI_ROOT_ORIGIN_ALLOCATED) { 420 ACPI_FREE(acpi_gbl_root_table_list.tables); 421 } 422 423 acpi_gbl_root_table_list.tables = NULL; 424 acpi_gbl_root_table_list.flags = 0; 425 acpi_gbl_root_table_list.count = 0; 426 427 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "ACPI Tables freed\n")); 428 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); 429 } 430 431 /******************************************************************************* 432 * 433 * FUNCTION: acpi_tb_delete_namespace_by_owner 434 * 435 * PARAMETERS: table_index - Table index 436 * 437 * RETURN: Status 438 * 439 * DESCRIPTION: Delete all namespace objects created when this table was loaded. 440 * 441 ******************************************************************************/ 442 443 acpi_status acpi_tb_delete_namespace_by_owner(u32 table_index) 444 { 445 acpi_owner_id owner_id; 446 acpi_status status; 447 448 ACPI_FUNCTION_TRACE(tb_delete_namespace_by_owner); 449 450 status = acpi_ut_acquire_mutex(ACPI_MTX_TABLES); 451 if (ACPI_FAILURE(status)) { 452 return_ACPI_STATUS(status); 453 } 454 455 if (table_index >= acpi_gbl_root_table_list.count) { 456 457 /* The table index does not exist */ 458 459 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); 460 return_ACPI_STATUS(AE_NOT_EXIST); 461 } 462 463 /* Get the owner ID for this table, used to delete namespace nodes */ 464 465 owner_id = acpi_gbl_root_table_list.tables[table_index].owner_id; 466 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); 467 468 /* 469 * Need to acquire the namespace writer lock to prevent interference 470 * with any concurrent namespace walks. The interpreter must be 471 * released during the deletion since the acquisition of the deletion 472 * lock may block, and also since the execution of a namespace walk 473 * must be allowed to use the interpreter. 474 */ 475 acpi_ut_release_mutex(ACPI_MTX_INTERPRETER); 476 status = acpi_ut_acquire_write_lock(&acpi_gbl_namespace_rw_lock); 477 478 acpi_ns_delete_namespace_by_owner(owner_id); 479 if (ACPI_FAILURE(status)) { 480 return_ACPI_STATUS(status); 481 } 482 483 acpi_ut_release_write_lock(&acpi_gbl_namespace_rw_lock); 484 485 status = acpi_ut_acquire_mutex(ACPI_MTX_INTERPRETER); 486 return_ACPI_STATUS(status); 487 } 488 489 /******************************************************************************* 490 * 491 * FUNCTION: acpi_tb_allocate_owner_id 492 * 493 * PARAMETERS: table_index - Table index 494 * 495 * RETURN: Status 496 * 497 * DESCRIPTION: Allocates owner_id in table_desc 498 * 499 ******************************************************************************/ 500 501 acpi_status acpi_tb_allocate_owner_id(u32 table_index) 502 { 503 acpi_status status = AE_BAD_PARAMETER; 504 505 ACPI_FUNCTION_TRACE(tb_allocate_owner_id); 506 507 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); 508 if (table_index < acpi_gbl_root_table_list.count) { 509 status = acpi_ut_allocate_owner_id 510 (&(acpi_gbl_root_table_list.tables[table_index].owner_id)); 511 } 512 513 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); 514 return_ACPI_STATUS(status); 515 } 516 517 /******************************************************************************* 518 * 519 * FUNCTION: acpi_tb_release_owner_id 520 * 521 * PARAMETERS: table_index - Table index 522 * 523 * RETURN: Status 524 * 525 * DESCRIPTION: Releases owner_id in table_desc 526 * 527 ******************************************************************************/ 528 529 acpi_status acpi_tb_release_owner_id(u32 table_index) 530 { 531 acpi_status status = AE_BAD_PARAMETER; 532 533 ACPI_FUNCTION_TRACE(tb_release_owner_id); 534 535 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); 536 if (table_index < acpi_gbl_root_table_list.count) { 537 acpi_ut_release_owner_id(& 538 (acpi_gbl_root_table_list. 539 tables[table_index].owner_id)); 540 status = AE_OK; 541 } 542 543 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); 544 return_ACPI_STATUS(status); 545 } 546 547 /******************************************************************************* 548 * 549 * FUNCTION: acpi_tb_get_owner_id 550 * 551 * PARAMETERS: table_index - Table index 552 * owner_id - Where the table owner_id is returned 553 * 554 * RETURN: Status 555 * 556 * DESCRIPTION: returns owner_id for the ACPI table 557 * 558 ******************************************************************************/ 559 560 acpi_status acpi_tb_get_owner_id(u32 table_index, acpi_owner_id *owner_id) 561 { 562 acpi_status status = AE_BAD_PARAMETER; 563 564 ACPI_FUNCTION_TRACE(tb_get_owner_id); 565 566 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); 567 if (table_index < acpi_gbl_root_table_list.count) { 568 *owner_id = 569 acpi_gbl_root_table_list.tables[table_index].owner_id; 570 status = AE_OK; 571 } 572 573 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); 574 return_ACPI_STATUS(status); 575 } 576 577 /******************************************************************************* 578 * 579 * FUNCTION: acpi_tb_is_table_loaded 580 * 581 * PARAMETERS: table_index - Table index 582 * 583 * RETURN: Table Loaded Flag 584 * 585 ******************************************************************************/ 586 587 u8 acpi_tb_is_table_loaded(u32 table_index) 588 { 589 u8 is_loaded = FALSE; 590 591 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); 592 if (table_index < acpi_gbl_root_table_list.count) { 593 is_loaded = (u8) 594 (acpi_gbl_root_table_list.tables[table_index].flags & 595 ACPI_TABLE_IS_LOADED); 596 } 597 598 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); 599 return (is_loaded); 600 } 601 602 /******************************************************************************* 603 * 604 * FUNCTION: acpi_tb_set_table_loaded_flag 605 * 606 * PARAMETERS: table_index - Table index 607 * is_loaded - TRUE if table is loaded, FALSE otherwise 608 * 609 * RETURN: None 610 * 611 * DESCRIPTION: Sets the table loaded flag to either TRUE or FALSE. 612 * 613 ******************************************************************************/ 614 615 void acpi_tb_set_table_loaded_flag(u32 table_index, u8 is_loaded) 616 { 617 618 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); 619 if (table_index < acpi_gbl_root_table_list.count) { 620 if (is_loaded) { 621 acpi_gbl_root_table_list.tables[table_index].flags |= 622 ACPI_TABLE_IS_LOADED; 623 } else { 624 acpi_gbl_root_table_list.tables[table_index].flags &= 625 ~ACPI_TABLE_IS_LOADED; 626 } 627 } 628 629 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); 630 } 631