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 the ACPI table 107 * 108 ******************************************************************************/ 109 110 acpi_status 111 acpi_tb_add_table(struct acpi_table_desc *table_desc, u32 *table_index) 112 { 113 u32 i; 114 acpi_status status = AE_OK; 115 116 ACPI_FUNCTION_TRACE(tb_add_table); 117 118 if (!table_desc->pointer) { 119 status = acpi_tb_verify_table(table_desc); 120 if (ACPI_FAILURE(status) || !table_desc->pointer) { 121 return_ACPI_STATUS(status); 122 } 123 } 124 125 /* 126 * Originally, we checked the table signature for "SSDT" or "PSDT" here. 127 * Next, we added support for OEMx tables, signature "OEM". 128 * Valid tables were encountered with a null signature, so we've just 129 * given up on validating the signature, since it seems to be a waste 130 * of code. The original code was removed (05/2008). 131 */ 132 133 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); 134 135 /* Check if table is already registered */ 136 137 for (i = 0; i < acpi_gbl_root_table_list.count; ++i) { 138 if (!acpi_gbl_root_table_list.tables[i].pointer) { 139 status = 140 acpi_tb_verify_table(&acpi_gbl_root_table_list. 141 tables[i]); 142 if (ACPI_FAILURE(status) 143 || !acpi_gbl_root_table_list.tables[i].pointer) { 144 continue; 145 } 146 } 147 148 /* 149 * Check for a table match on the entire table length, 150 * not just the header. 151 */ 152 if (table_desc->length != 153 acpi_gbl_root_table_list.tables[i].length) { 154 continue; 155 } 156 157 if (ACPI_MEMCMP(table_desc->pointer, 158 acpi_gbl_root_table_list.tables[i].pointer, 159 acpi_gbl_root_table_list.tables[i].length)) { 160 continue; 161 } 162 163 /* 164 * Note: the current mechanism does not unregister a table if it is 165 * dynamically unloaded. The related namespace entries are deleted, 166 * but the table remains in the root table list. 167 * 168 * The assumption here is that the number of different tables that 169 * will be loaded is actually small, and there is minimal overhead 170 * in just keeping the table in case it is needed again. 171 * 172 * If this assumption changes in the future (perhaps on large 173 * machines with many table load/unload operations), tables will 174 * need to be unregistered when they are unloaded, and slots in the 175 * root table list should be reused when empty. 176 */ 177 178 /* 179 * Table is already registered. 180 * We can delete the table that was passed as a parameter. 181 */ 182 acpi_tb_delete_table(table_desc); 183 *table_index = i; 184 185 if (acpi_gbl_root_table_list.tables[i]. 186 flags & ACPI_TABLE_IS_LOADED) { 187 188 /* Table is still loaded, this is an error */ 189 190 status = AE_ALREADY_EXISTS; 191 goto release; 192 } else { 193 /* Table was unloaded, allow it to be reloaded */ 194 195 table_desc->pointer = 196 acpi_gbl_root_table_list.tables[i].pointer; 197 table_desc->address = 198 acpi_gbl_root_table_list.tables[i].address; 199 status = AE_OK; 200 goto print_header; 201 } 202 } 203 204 /* Add the table to the global root table list */ 205 206 status = acpi_tb_store_table(table_desc->address, table_desc->pointer, 207 table_desc->length, table_desc->flags, 208 table_index); 209 if (ACPI_FAILURE(status)) { 210 goto release; 211 } 212 213 print_header: 214 acpi_tb_print_table_header(table_desc->address, table_desc->pointer); 215 216 release: 217 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); 218 return_ACPI_STATUS(status); 219 } 220 221 /******************************************************************************* 222 * 223 * FUNCTION: acpi_tb_resize_root_table_list 224 * 225 * PARAMETERS: None 226 * 227 * RETURN: Status 228 * 229 * DESCRIPTION: Expand the size of global table array 230 * 231 ******************************************************************************/ 232 233 acpi_status acpi_tb_resize_root_table_list(void) 234 { 235 struct acpi_table_desc *tables; 236 237 ACPI_FUNCTION_TRACE(tb_resize_root_table_list); 238 239 /* allow_resize flag is a parameter to acpi_initialize_tables */ 240 241 if (!(acpi_gbl_root_table_list.flags & ACPI_ROOT_ALLOW_RESIZE)) { 242 ACPI_ERROR((AE_INFO, 243 "Resize of Root Table Array is not allowed")); 244 return_ACPI_STATUS(AE_SUPPORT); 245 } 246 247 /* Increase the Table Array size */ 248 249 tables = ACPI_ALLOCATE_ZEROED(((acpi_size) acpi_gbl_root_table_list. 250 size + ACPI_ROOT_TABLE_SIZE_INCREMENT) 251 * sizeof(struct acpi_table_desc)); 252 if (!tables) { 253 ACPI_ERROR((AE_INFO, 254 "Could not allocate new root table array")); 255 return_ACPI_STATUS(AE_NO_MEMORY); 256 } 257 258 /* Copy and free the previous table array */ 259 260 if (acpi_gbl_root_table_list.tables) { 261 ACPI_MEMCPY(tables, acpi_gbl_root_table_list.tables, 262 (acpi_size) acpi_gbl_root_table_list.size * 263 sizeof(struct acpi_table_desc)); 264 265 if (acpi_gbl_root_table_list.flags & ACPI_ROOT_ORIGIN_ALLOCATED) { 266 ACPI_FREE(acpi_gbl_root_table_list.tables); 267 } 268 } 269 270 acpi_gbl_root_table_list.tables = tables; 271 acpi_gbl_root_table_list.size += ACPI_ROOT_TABLE_SIZE_INCREMENT; 272 acpi_gbl_root_table_list.flags |= (u8) ACPI_ROOT_ORIGIN_ALLOCATED; 273 274 return_ACPI_STATUS(AE_OK); 275 } 276 277 /******************************************************************************* 278 * 279 * FUNCTION: acpi_tb_store_table 280 * 281 * PARAMETERS: Address - Table address 282 * Table - Table header 283 * Length - Table length 284 * Flags - flags 285 * 286 * RETURN: Status and table index. 287 * 288 * DESCRIPTION: Add an ACPI table to the global table list 289 * 290 ******************************************************************************/ 291 292 acpi_status 293 acpi_tb_store_table(acpi_physical_address address, 294 struct acpi_table_header *table, 295 u32 length, u8 flags, u32 *table_index) 296 { 297 acpi_status status = AE_OK; 298 299 /* Ensure that there is room for the table in the Root Table List */ 300 301 if (acpi_gbl_root_table_list.count >= acpi_gbl_root_table_list.size) { 302 status = acpi_tb_resize_root_table_list(); 303 if (ACPI_FAILURE(status)) { 304 return (status); 305 } 306 } 307 308 /* Initialize added table */ 309 310 acpi_gbl_root_table_list.tables[acpi_gbl_root_table_list.count]. 311 address = address; 312 acpi_gbl_root_table_list.tables[acpi_gbl_root_table_list.count]. 313 pointer = table; 314 acpi_gbl_root_table_list.tables[acpi_gbl_root_table_list.count].length = 315 length; 316 acpi_gbl_root_table_list.tables[acpi_gbl_root_table_list.count]. 317 owner_id = 0; 318 acpi_gbl_root_table_list.tables[acpi_gbl_root_table_list.count].flags = 319 flags; 320 321 ACPI_MOVE_32_TO_32(& 322 (acpi_gbl_root_table_list. 323 tables[acpi_gbl_root_table_list.count].signature), 324 table->signature); 325 326 *table_index = acpi_gbl_root_table_list.count; 327 acpi_gbl_root_table_list.count++; 328 return (status); 329 } 330 331 /******************************************************************************* 332 * 333 * FUNCTION: acpi_tb_delete_table 334 * 335 * PARAMETERS: table_index - Table index 336 * 337 * RETURN: None 338 * 339 * DESCRIPTION: Delete one internal ACPI table 340 * 341 ******************************************************************************/ 342 343 void acpi_tb_delete_table(struct acpi_table_desc *table_desc) 344 { 345 /* Table must be mapped or allocated */ 346 if (!table_desc->pointer) { 347 return; 348 } 349 switch (table_desc->flags & ACPI_TABLE_ORIGIN_MASK) { 350 case ACPI_TABLE_ORIGIN_MAPPED: 351 acpi_os_unmap_memory(table_desc->pointer, table_desc->length); 352 break; 353 case ACPI_TABLE_ORIGIN_ALLOCATED: 354 ACPI_FREE(table_desc->pointer); 355 break; 356 default:; 357 } 358 359 table_desc->pointer = NULL; 360 } 361 362 /******************************************************************************* 363 * 364 * FUNCTION: acpi_tb_terminate 365 * 366 * PARAMETERS: None 367 * 368 * RETURN: None 369 * 370 * DESCRIPTION: Delete all internal ACPI tables 371 * 372 ******************************************************************************/ 373 374 void acpi_tb_terminate(void) 375 { 376 u32 i; 377 378 ACPI_FUNCTION_TRACE(tb_terminate); 379 380 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); 381 382 /* Delete the individual tables */ 383 384 for (i = 0; i < acpi_gbl_root_table_list.count; ++i) { 385 acpi_tb_delete_table(&acpi_gbl_root_table_list.tables[i]); 386 } 387 388 /* 389 * Delete the root table array if allocated locally. Array cannot be 390 * mapped, so we don't need to check for that flag. 391 */ 392 if (acpi_gbl_root_table_list.flags & ACPI_ROOT_ORIGIN_ALLOCATED) { 393 ACPI_FREE(acpi_gbl_root_table_list.tables); 394 } 395 396 acpi_gbl_root_table_list.tables = NULL; 397 acpi_gbl_root_table_list.flags = 0; 398 acpi_gbl_root_table_list.count = 0; 399 400 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "ACPI Tables freed\n")); 401 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); 402 } 403 404 /******************************************************************************* 405 * 406 * FUNCTION: acpi_tb_delete_namespace_by_owner 407 * 408 * PARAMETERS: table_index - Table index 409 * 410 * RETURN: None 411 * 412 * DESCRIPTION: Delete all namespace objects created when this table was loaded. 413 * 414 ******************************************************************************/ 415 416 void acpi_tb_delete_namespace_by_owner(u32 table_index) 417 { 418 acpi_owner_id owner_id; 419 420 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); 421 if (table_index < acpi_gbl_root_table_list.count) { 422 owner_id = 423 acpi_gbl_root_table_list.tables[table_index].owner_id; 424 } else { 425 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); 426 return; 427 } 428 429 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); 430 acpi_ns_delete_namespace_by_owner(owner_id); 431 } 432 433 /******************************************************************************* 434 * 435 * FUNCTION: acpi_tb_allocate_owner_id 436 * 437 * PARAMETERS: table_index - Table index 438 * 439 * RETURN: Status 440 * 441 * DESCRIPTION: Allocates owner_id in table_desc 442 * 443 ******************************************************************************/ 444 445 acpi_status acpi_tb_allocate_owner_id(u32 table_index) 446 { 447 acpi_status status = AE_BAD_PARAMETER; 448 449 ACPI_FUNCTION_TRACE(tb_allocate_owner_id); 450 451 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); 452 if (table_index < acpi_gbl_root_table_list.count) { 453 status = acpi_ut_allocate_owner_id 454 (&(acpi_gbl_root_table_list.tables[table_index].owner_id)); 455 } 456 457 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); 458 return_ACPI_STATUS(status); 459 } 460 461 /******************************************************************************* 462 * 463 * FUNCTION: acpi_tb_release_owner_id 464 * 465 * PARAMETERS: table_index - Table index 466 * 467 * RETURN: Status 468 * 469 * DESCRIPTION: Releases owner_id in table_desc 470 * 471 ******************************************************************************/ 472 473 acpi_status acpi_tb_release_owner_id(u32 table_index) 474 { 475 acpi_status status = AE_BAD_PARAMETER; 476 477 ACPI_FUNCTION_TRACE(tb_release_owner_id); 478 479 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); 480 if (table_index < acpi_gbl_root_table_list.count) { 481 acpi_ut_release_owner_id(& 482 (acpi_gbl_root_table_list. 483 tables[table_index].owner_id)); 484 status = AE_OK; 485 } 486 487 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); 488 return_ACPI_STATUS(status); 489 } 490 491 /******************************************************************************* 492 * 493 * FUNCTION: acpi_tb_get_owner_id 494 * 495 * PARAMETERS: table_index - Table index 496 * owner_id - Where the table owner_id is returned 497 * 498 * RETURN: Status 499 * 500 * DESCRIPTION: returns owner_id for the ACPI table 501 * 502 ******************************************************************************/ 503 504 acpi_status acpi_tb_get_owner_id(u32 table_index, acpi_owner_id *owner_id) 505 { 506 acpi_status status = AE_BAD_PARAMETER; 507 508 ACPI_FUNCTION_TRACE(tb_get_owner_id); 509 510 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); 511 if (table_index < acpi_gbl_root_table_list.count) { 512 *owner_id = 513 acpi_gbl_root_table_list.tables[table_index].owner_id; 514 status = AE_OK; 515 } 516 517 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); 518 return_ACPI_STATUS(status); 519 } 520 521 /******************************************************************************* 522 * 523 * FUNCTION: acpi_tb_is_table_loaded 524 * 525 * PARAMETERS: table_index - Table index 526 * 527 * RETURN: Table Loaded Flag 528 * 529 ******************************************************************************/ 530 531 u8 acpi_tb_is_table_loaded(u32 table_index) 532 { 533 u8 is_loaded = FALSE; 534 535 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); 536 if (table_index < acpi_gbl_root_table_list.count) { 537 is_loaded = (u8) 538 (acpi_gbl_root_table_list.tables[table_index]. 539 flags & ACPI_TABLE_IS_LOADED); 540 } 541 542 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); 543 return (is_loaded); 544 } 545 546 /******************************************************************************* 547 * 548 * FUNCTION: acpi_tb_set_table_loaded_flag 549 * 550 * PARAMETERS: table_index - Table index 551 * is_loaded - TRUE if table is loaded, FALSE otherwise 552 * 553 * RETURN: None 554 * 555 * DESCRIPTION: Sets the table loaded flag to either TRUE or FALSE. 556 * 557 ******************************************************************************/ 558 559 void acpi_tb_set_table_loaded_flag(u32 table_index, u8 is_loaded) 560 { 561 562 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); 563 if (table_index < acpi_gbl_root_table_list.count) { 564 if (is_loaded) { 565 acpi_gbl_root_table_list.tables[table_index].flags |= 566 ACPI_TABLE_IS_LOADED; 567 } else { 568 acpi_gbl_root_table_list.tables[table_index].flags &= 569 ~ACPI_TABLE_IS_LOADED; 570 } 571 } 572 573 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); 574 } 575