1/****************************************************************************** 2 * 3 * Module Name: tbxface - Public interfaces to the ACPI subsystem 4 * ACPI table oriented interfaces 5 * 6 *****************************************************************************/ 7 8/* 9 * Copyright (C) 2000 - 2007, R. Byron Moore 10 * All rights reserved. 11 * 12 * Redistribution and use in source and binary forms, with or without 13 * modification, are permitted provided that the following conditions 14 * are met: 15 * 1. Redistributions of source code must retain the above copyright 16 * notice, this list of conditions, and the following disclaimer, 17 * without modification. 18 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 19 * substantially similar to the "NO WARRANTY" disclaimer below 20 * ("Disclaimer") and any redistribution must be conditioned upon 21 * including a substantially similar Disclaimer requirement for further 22 * binary redistribution. 23 * 3. Neither the names of the above-listed copyright holders nor the names 24 * of any contributors may be used to endorse or promote products derived 25 * from this software without specific prior written permission. 26 * 27 * Alternatively, this software may be distributed under the terms of the 28 * GNU General Public License ("GPL") version 2 as published by the Free 29 * Software Foundation. 30 * 31 * NO WARRANTY 32 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 33 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 34 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 35 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 36 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 37 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 38 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 39 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 40 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 41 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 42 * POSSIBILITY OF SUCH DAMAGES. 43 */ 44 45#include <acpi/acpi.h> 46#include <acpi/acnamesp.h> 47#include <acpi/actables.h> 48 49#define _COMPONENT ACPI_TABLES 50ACPI_MODULE_NAME("tbxface") 51 52/* Local prototypes */ 53static acpi_status acpi_tb_load_namespace(void); 54 55/******************************************************************************* 56 * 57 * FUNCTION: acpi_allocate_root_table 58 * 59 * PARAMETERS: initial_table_count - Size of initial_table_array, in number of 60 * struct acpi_table_desc structures 61 * 62 * RETURN: Status 63 * 64 * DESCRIPTION: Allocate a root table array. Used by i_aSL compiler and 65 * acpi_initialize_tables. 66 * 67 ******************************************************************************/ 68 69acpi_status acpi_allocate_root_table(u32 initial_table_count) 70{ 71 72 acpi_gbl_root_table_list.size = initial_table_count; 73 acpi_gbl_root_table_list.flags = ACPI_ROOT_ALLOW_RESIZE; 74 75 return (acpi_tb_resize_root_table_list()); 76} 77 78/******************************************************************************* 79 * 80 * FUNCTION: acpi_initialize_tables 81 * 82 * PARAMETERS: initial_table_array - Pointer to an array of pre-allocated 83 * struct acpi_table_desc structures. If NULL, the 84 * array is dynamically allocated. 85 * initial_table_count - Size of initial_table_array, in number of 86 * struct acpi_table_desc structures 87 * allow_realloc - Flag to tell Table Manager if resize of 88 * pre-allocated array is allowed. Ignored 89 * if initial_table_array is NULL. 90 * 91 * RETURN: Status 92 * 93 * DESCRIPTION: Initialize the table manager, get the RSDP and RSDT/XSDT. 94 * 95 * NOTE: Allows static allocation of the initial table array in order 96 * to avoid the use of dynamic memory in confined environments 97 * such as the kernel boot sequence where it may not be available. 98 * 99 * If the host OS memory managers are initialized, use NULL for 100 * initial_table_array, and the table will be dynamically allocated. 101 * 102 ******************************************************************************/ 103 104acpi_status __init 105acpi_initialize_tables(struct acpi_table_desc * initial_table_array, 106 u32 initial_table_count, u8 allow_resize) 107{ 108 acpi_physical_address rsdp_address; 109 acpi_status status; 110 111 ACPI_FUNCTION_TRACE(acpi_initialize_tables); 112 113 /* 114 * Set up the Root Table Array 115 * Allocate the table array if requested 116 */ 117 if (!initial_table_array) { 118 status = acpi_allocate_root_table(initial_table_count); 119 if (ACPI_FAILURE(status)) { 120 return_ACPI_STATUS(status); 121 } 122 } else { 123 /* Root Table Array has been statically allocated by the host */ 124 125 ACPI_MEMSET(initial_table_array, 0, 126 initial_table_count * 127 sizeof(struct acpi_table_desc)); 128 129 acpi_gbl_root_table_list.tables = initial_table_array; 130 acpi_gbl_root_table_list.size = initial_table_count; 131 acpi_gbl_root_table_list.flags = ACPI_ROOT_ORIGIN_UNKNOWN; 132 if (allow_resize) { 133 acpi_gbl_root_table_list.flags |= 134 ACPI_ROOT_ALLOW_RESIZE; 135 } 136 } 137 138 /* Get the address of the RSDP */ 139 140 rsdp_address = acpi_os_get_root_pointer(); 141 if (!rsdp_address) { 142 return_ACPI_STATUS(AE_NOT_FOUND); 143 } 144 145 /* 146 * Get the root table (RSDT or XSDT) and extract all entries to the local 147 * Root Table Array. This array contains the information of the RSDT/XSDT 148 * in a common, more useable format. 149 */ 150 status = 151 acpi_tb_parse_root_table(rsdp_address, ACPI_TABLE_ORIGIN_MAPPED); 152 return_ACPI_STATUS(status); 153} 154 155/******************************************************************************* 156 * 157 * FUNCTION: acpi_reallocate_root_table 158 * 159 * PARAMETERS: None 160 * 161 * RETURN: Status 162 * 163 * DESCRIPTION: Reallocate Root Table List into dynamic memory. Copies the 164 * root list from the previously provided scratch area. Should 165 * be called once dynamic memory allocation is available in the 166 * kernel 167 * 168 ******************************************************************************/ 169acpi_status acpi_reallocate_root_table(void) 170{ 171 struct acpi_table_desc *tables; 172 acpi_size new_size; 173 174 ACPI_FUNCTION_TRACE(acpi_reallocate_root_table); 175 176 /* 177 * Only reallocate the root table if the host provided a static buffer 178 * for the table array in the call to acpi_initialize_tables. 179 */ 180 if (acpi_gbl_root_table_list.flags & ACPI_ROOT_ORIGIN_ALLOCATED) { 181 return_ACPI_STATUS(AE_SUPPORT); 182 } 183 184 new_size = 185 (acpi_gbl_root_table_list.count + 186 ACPI_ROOT_TABLE_SIZE_INCREMENT) * sizeof(struct acpi_table_desc); 187 188 /* Create new array and copy the old array */ 189 190 tables = ACPI_ALLOCATE_ZEROED(new_size); 191 if (!tables) { 192 return_ACPI_STATUS(AE_NO_MEMORY); 193 } 194 195 ACPI_MEMCPY(tables, acpi_gbl_root_table_list.tables, new_size); 196 197 acpi_gbl_root_table_list.size = acpi_gbl_root_table_list.count; 198 acpi_gbl_root_table_list.tables = tables; 199 acpi_gbl_root_table_list.flags = 200 ACPI_ROOT_ORIGIN_ALLOCATED | ACPI_ROOT_ALLOW_RESIZE; 201 202 return_ACPI_STATUS(AE_OK); 203} 204 205/******************************************************************************* 206 * 207 * FUNCTION: acpi_load_table 208 * 209 * PARAMETERS: table_ptr - pointer to a buffer containing the entire 210 * table to be loaded 211 * 212 * RETURN: Status 213 * 214 * DESCRIPTION: This function is called to load a table from the caller's 215 * buffer. The buffer must contain an entire ACPI Table including 216 * a valid header. The header fields will be verified, and if it 217 * is determined that the table is invalid, the call will fail. 218 * 219 ******************************************************************************/ 220acpi_status acpi_load_table(struct acpi_table_header *table_ptr) 221{ 222 acpi_status status; 223 acpi_native_uint table_index; 224 struct acpi_table_desc table_desc; 225 226 if (!table_ptr) 227 return AE_BAD_PARAMETER; 228 229 ACPI_MEMSET(&table_desc, 0, sizeof(struct acpi_table_desc)); 230 table_desc.pointer = table_ptr; 231 table_desc.length = table_ptr->length; 232 table_desc.flags = ACPI_TABLE_ORIGIN_UNKNOWN; 233 234 /* 235 * Install the new table into the local data structures 236 */ 237 status = acpi_tb_add_table(&table_desc, &table_index); 238 if (ACPI_FAILURE(status)) { 239 return status; 240 } 241 status = acpi_ns_load_table(table_index, acpi_gbl_root_node); 242 return status; 243} 244 245ACPI_EXPORT_SYMBOL(acpi_load_table) 246 247/****************************************************************************** 248 * 249 * FUNCTION: acpi_get_table_header 250 * 251 * PARAMETERS: Signature - ACPI signature of needed table 252 * Instance - Which instance (for SSDTs) 253 * out_table_header - The pointer to the table header to fill 254 * 255 * RETURN: Status and pointer to mapped table header 256 * 257 * DESCRIPTION: Finds an ACPI table header. 258 * 259 * NOTE: Caller is responsible in unmapping the header with 260 * acpi_os_unmap_memory 261 * 262 *****************************************************************************/ 263acpi_status 264acpi_get_table_header(char *signature, 265 acpi_native_uint instance, 266 struct acpi_table_header * out_table_header) 267{ 268 acpi_native_uint i; 269 acpi_native_uint j; 270 struct acpi_table_header *header; 271 272 /* Parameter validation */ 273 274 if (!signature || !out_table_header) { 275 return (AE_BAD_PARAMETER); 276 } 277 278 /* 279 * Walk the root table list 280 */ 281 for (i = 0, j = 0; i < acpi_gbl_root_table_list.count; i++) { 282 if (!ACPI_COMPARE_NAME 283 (&(acpi_gbl_root_table_list.tables[i].signature), 284 signature)) { 285 continue; 286 } 287 288 if (++j < instance) { 289 continue; 290 } 291 292 if (!acpi_gbl_root_table_list.tables[i].pointer) { 293 if ((acpi_gbl_root_table_list.tables[i]. 294 flags & ACPI_TABLE_ORIGIN_MASK) == 295 ACPI_TABLE_ORIGIN_MAPPED) { 296 header = 297 acpi_os_map_memory(acpi_gbl_root_table_list. 298 tables[i].address, 299 sizeof(struct 300 acpi_table_header)); 301 if (!header) { 302 return AE_NO_MEMORY; 303 } 304 ACPI_MEMCPY(out_table_header, header, 305 sizeof(struct acpi_table_header)); 306 acpi_os_unmap_memory(header, 307 sizeof(struct 308 acpi_table_header)); 309 } else { 310 return AE_NOT_FOUND; 311 } 312 } else { 313 ACPI_MEMCPY(out_table_header, 314 acpi_gbl_root_table_list.tables[i].pointer, 315 sizeof(struct acpi_table_header)); 316 } 317 return (AE_OK); 318 } 319 320 return (AE_NOT_FOUND); 321} 322 323ACPI_EXPORT_SYMBOL(acpi_get_table_header) 324 325/****************************************************************************** 326 * 327 * FUNCTION: acpi_unload_table_id 328 * 329 * PARAMETERS: id - Owner ID of the table to be removed. 330 * 331 * RETURN: Status 332 * 333 * DESCRIPTION: This routine is used to force the unload of a table (by id) 334 * 335 ******************************************************************************/ 336acpi_status acpi_unload_table_id(acpi_owner_id id) 337{ 338 int i; 339 acpi_status status = AE_NOT_EXIST; 340 341 ACPI_FUNCTION_TRACE(acpi_unload_table_id); 342 343 /* Find table in the global table list */ 344 for (i = 0; i < acpi_gbl_root_table_list.count; ++i) { 345 if (id != acpi_gbl_root_table_list.tables[i].owner_id) { 346 continue; 347 } 348 /* 349 * Delete all namespace objects owned by this table. Note that these 350 * objects can appear anywhere in the namespace by virtue of the AML 351 * "Scope" operator. Thus, we need to track ownership by an ID, not 352 * simply a position within the hierarchy 353 */ 354 acpi_tb_delete_namespace_by_owner(i); 355 status = acpi_tb_release_owner_id(i); 356 acpi_tb_set_table_loaded_flag(i, FALSE); 357 break; 358 } 359 return_ACPI_STATUS(status); 360} 361 362ACPI_EXPORT_SYMBOL(acpi_unload_table_id) 363 364/******************************************************************************* 365 * 366 * FUNCTION: acpi_get_table 367 * 368 * PARAMETERS: Signature - ACPI signature of needed table 369 * Instance - Which instance (for SSDTs) 370 * out_table - Where the pointer to the table is returned 371 * 372 * RETURN: Status and pointer to table 373 * 374 * DESCRIPTION: Finds and verifies an ACPI table. 375 * 376 *****************************************************************************/ 377acpi_status 378acpi_get_table(char *signature, 379 acpi_native_uint instance, struct acpi_table_header **out_table) 380{ 381 acpi_native_uint i; 382 acpi_native_uint j; 383 acpi_status status; 384 385 /* Parameter validation */ 386 387 if (!signature || !out_table) { 388 return (AE_BAD_PARAMETER); 389 } 390 391 /* 392 * Walk the root table list 393 */ 394 for (i = 0, j = 0; i < acpi_gbl_root_table_list.count; i++) { 395 if (!ACPI_COMPARE_NAME 396 (&(acpi_gbl_root_table_list.tables[i].signature), 397 signature)) { 398 continue; 399 } 400 401 if (++j < instance) { 402 continue; 403 } 404 405 status = 406 acpi_tb_verify_table(&acpi_gbl_root_table_list.tables[i]); 407 if (ACPI_SUCCESS(status)) { 408 *out_table = acpi_gbl_root_table_list.tables[i].pointer; 409 } 410 411 if (!acpi_gbl_permanent_mmap) { 412 acpi_gbl_root_table_list.tables[i].pointer = NULL; 413 } 414 415 return (status); 416 } 417 418 return (AE_NOT_FOUND); 419} 420 421ACPI_EXPORT_SYMBOL(acpi_get_table) 422 423/******************************************************************************* 424 * 425 * FUNCTION: acpi_get_table_by_index 426 * 427 * PARAMETERS: table_index - Table index 428 * Table - Where the pointer to the table is returned 429 * 430 * RETURN: Status and pointer to the table 431 * 432 * DESCRIPTION: Obtain a table by an index into the global table list. 433 * 434 ******************************************************************************/ 435acpi_status 436acpi_get_table_by_index(acpi_native_uint table_index, 437 struct acpi_table_header ** table) 438{ 439 acpi_status status; 440 441 ACPI_FUNCTION_TRACE(acpi_get_table_by_index); 442 443 /* Parameter validation */ 444 445 if (!table) { 446 return_ACPI_STATUS(AE_BAD_PARAMETER); 447 } 448 449 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); 450 451 /* Validate index */ 452 453 if (table_index >= acpi_gbl_root_table_list.count) { 454 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); 455 return_ACPI_STATUS(AE_BAD_PARAMETER); 456 } 457 458 if (!acpi_gbl_root_table_list.tables[table_index].pointer) { 459 460 /* Table is not mapped, map it */ 461 462 status = 463 acpi_tb_verify_table(&acpi_gbl_root_table_list. 464 tables[table_index]); 465 if (ACPI_FAILURE(status)) { 466 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); 467 return_ACPI_STATUS(status); 468 } 469 } 470 471 *table = acpi_gbl_root_table_list.tables[table_index].pointer; 472 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); 473 return_ACPI_STATUS(AE_OK); 474} 475 476ACPI_EXPORT_SYMBOL(acpi_get_table_by_index) 477 478/******************************************************************************* 479 * 480 * FUNCTION: acpi_tb_load_namespace 481 * 482 * PARAMETERS: None 483 * 484 * RETURN: Status 485 * 486 * DESCRIPTION: Load the namespace from the DSDT and all SSDTs/PSDTs found in 487 * the RSDT/XSDT. 488 * 489 ******************************************************************************/ 490static acpi_status acpi_tb_load_namespace(void) 491{ 492 acpi_status status; 493 struct acpi_table_header *table; 494 acpi_native_uint i; 495 496 ACPI_FUNCTION_TRACE(tb_load_namespace); 497 498 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); 499 500 /* 501 * Load the namespace. The DSDT is required, but any SSDT and PSDT tables 502 * are optional. 503 */ 504 if (!acpi_gbl_root_table_list.count || 505 !ACPI_COMPARE_NAME(& 506 (acpi_gbl_root_table_list. 507 tables[ACPI_TABLE_INDEX_DSDT].signature), 508 ACPI_SIG_DSDT) 509 || 510 ACPI_FAILURE(acpi_tb_verify_table 511 (&acpi_gbl_root_table_list. 512 tables[ACPI_TABLE_INDEX_DSDT]))) { 513 status = AE_NO_ACPI_TABLES; 514 goto unlock_and_exit; 515 } 516 517 /* 518 * Find DSDT table 519 */ 520 status = 521 acpi_os_table_override(acpi_gbl_root_table_list. 522 tables[ACPI_TABLE_INDEX_DSDT].pointer, 523 &table); 524 if (ACPI_SUCCESS(status) && table) { 525 /* 526 * DSDT table has been found 527 */ 528 acpi_tb_delete_table(&acpi_gbl_root_table_list. 529 tables[ACPI_TABLE_INDEX_DSDT]); 530 acpi_gbl_root_table_list.tables[ACPI_TABLE_INDEX_DSDT].pointer = 531 table; 532 acpi_gbl_root_table_list.tables[ACPI_TABLE_INDEX_DSDT].length = 533 table->length; 534 acpi_gbl_root_table_list.tables[ACPI_TABLE_INDEX_DSDT].flags = 535 ACPI_TABLE_ORIGIN_UNKNOWN; 536 537 ACPI_INFO((AE_INFO, "Table DSDT replaced by host OS")); 538 acpi_tb_print_table_header(0, table); 539 } 540 541 status = 542 acpi_tb_verify_table(&acpi_gbl_root_table_list. 543 tables[ACPI_TABLE_INDEX_DSDT]); 544 if (ACPI_FAILURE(status)) { 545 546 /* A valid DSDT is required */ 547 548 status = AE_NO_ACPI_TABLES; 549 goto unlock_and_exit; 550 } 551 552 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); 553 554 /* 555 * Load and parse tables. 556 */ 557 status = acpi_ns_load_table(ACPI_TABLE_INDEX_DSDT, acpi_gbl_root_node); 558 if (ACPI_FAILURE(status)) { 559 return_ACPI_STATUS(status); 560 } 561 562 /* 563 * Load any SSDT or PSDT tables. Note: Loop leaves tables locked 564 */ 565 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); 566 for (i = 0; i < acpi_gbl_root_table_list.count; ++i) { 567 if ((!ACPI_COMPARE_NAME 568 (&(acpi_gbl_root_table_list.tables[i].signature), 569 ACPI_SIG_SSDT) 570 && 571 !ACPI_COMPARE_NAME(& 572 (acpi_gbl_root_table_list.tables[i]. 573 signature), ACPI_SIG_PSDT)) 574 || 575 ACPI_FAILURE(acpi_tb_verify_table 576 (&acpi_gbl_root_table_list.tables[i]))) { 577 continue; 578 } 579 580 /* Ignore errors while loading tables, get as many as possible */ 581 582 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); 583 (void)acpi_ns_load_table(i, acpi_gbl_root_node); 584 (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); 585 } 586 587 ACPI_DEBUG_PRINT((ACPI_DB_INIT, "ACPI Tables successfully acquired\n")); 588 589 unlock_and_exit: 590 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); 591 return_ACPI_STATUS(status); 592} 593 594/******************************************************************************* 595 * 596 * FUNCTION: acpi_load_tables 597 * 598 * PARAMETERS: None 599 * 600 * RETURN: Status 601 * 602 * DESCRIPTION: Load the ACPI tables from the RSDT/XSDT 603 * 604 ******************************************************************************/ 605 606acpi_status acpi_load_tables(void) 607{ 608 acpi_status status; 609 610 ACPI_FUNCTION_TRACE(acpi_load_tables); 611 612 /* 613 * Load the namespace from the tables 614 */ 615 status = acpi_tb_load_namespace(); 616 if (ACPI_FAILURE(status)) { 617 ACPI_EXCEPTION((AE_INFO, status, 618 "While loading namespace from ACPI tables")); 619 } 620 621 return_ACPI_STATUS(status); 622} 623 624ACPI_EXPORT_SYMBOL(acpi_load_tables) 625