tbxface.c revision 217365
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 - 2011, Intel Corp. 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#define __TBXFACE_C__ 46 47#include <contrib/dev/acpica/include/acpi.h> 48#include <contrib/dev/acpica/include/accommon.h> 49#include <contrib/dev/acpica/include/acnamesp.h> 50#include <contrib/dev/acpica/include/actables.h> 51 52#define _COMPONENT ACPI_TABLES 53 ACPI_MODULE_NAME ("tbxface") 54 55/* Local prototypes */ 56 57static ACPI_STATUS 58AcpiTbLoadNamespace ( 59 void); 60 61 62/******************************************************************************* 63 * 64 * FUNCTION: AcpiAllocateRootTable 65 * 66 * PARAMETERS: InitialTableCount - Size of InitialTableArray, in number of 67 * ACPI_TABLE_DESC structures 68 * 69 * RETURN: Status 70 * 71 * DESCRIPTION: Allocate a root table array. Used by iASL compiler and 72 * AcpiInitializeTables. 73 * 74 ******************************************************************************/ 75 76ACPI_STATUS 77AcpiAllocateRootTable ( 78 UINT32 InitialTableCount) 79{ 80 81 AcpiGbl_RootTableList.MaxTableCount = InitialTableCount; 82 AcpiGbl_RootTableList.Flags = ACPI_ROOT_ALLOW_RESIZE; 83 84 return (AcpiTbResizeRootTableList ()); 85} 86 87 88/******************************************************************************* 89 * 90 * FUNCTION: AcpiInitializeTables 91 * 92 * PARAMETERS: InitialTableArray - Pointer to an array of pre-allocated 93 * ACPI_TABLE_DESC structures. If NULL, the 94 * array is dynamically allocated. 95 * InitialTableCount - Size of InitialTableArray, in number of 96 * ACPI_TABLE_DESC structures 97 * AllowRealloc - Flag to tell Table Manager if resize of 98 * pre-allocated array is allowed. Ignored 99 * if InitialTableArray is NULL. 100 * 101 * RETURN: Status 102 * 103 * DESCRIPTION: Initialize the table manager, get the RSDP and RSDT/XSDT. 104 * 105 * NOTE: Allows static allocation of the initial table array in order 106 * to avoid the use of dynamic memory in confined environments 107 * such as the kernel boot sequence where it may not be available. 108 * 109 * If the host OS memory managers are initialized, use NULL for 110 * InitialTableArray, and the table will be dynamically allocated. 111 * 112 ******************************************************************************/ 113 114ACPI_STATUS 115AcpiInitializeTables ( 116 ACPI_TABLE_DESC *InitialTableArray, 117 UINT32 InitialTableCount, 118 BOOLEAN AllowResize) 119{ 120 ACPI_PHYSICAL_ADDRESS RsdpAddress; 121 ACPI_STATUS Status; 122 123 124 ACPI_FUNCTION_TRACE (AcpiInitializeTables); 125 126 127 /* 128 * Set up the Root Table Array 129 * Allocate the table array if requested 130 */ 131 if (!InitialTableArray) 132 { 133 Status = AcpiAllocateRootTable (InitialTableCount); 134 if (ACPI_FAILURE (Status)) 135 { 136 return_ACPI_STATUS (Status); 137 } 138 } 139 else 140 { 141 /* Root Table Array has been statically allocated by the host */ 142 143 ACPI_MEMSET (InitialTableArray, 0, 144 (ACPI_SIZE) InitialTableCount * sizeof (ACPI_TABLE_DESC)); 145 146 AcpiGbl_RootTableList.Tables = InitialTableArray; 147 AcpiGbl_RootTableList.MaxTableCount = InitialTableCount; 148 AcpiGbl_RootTableList.Flags = ACPI_ROOT_ORIGIN_UNKNOWN; 149 if (AllowResize) 150 { 151 AcpiGbl_RootTableList.Flags |= ACPI_ROOT_ALLOW_RESIZE; 152 } 153 } 154 155 /* Get the address of the RSDP */ 156 157 RsdpAddress = AcpiOsGetRootPointer (); 158 if (!RsdpAddress) 159 { 160 return_ACPI_STATUS (AE_NOT_FOUND); 161 } 162 163 /* 164 * Get the root table (RSDT or XSDT) and extract all entries to the local 165 * Root Table Array. This array contains the information of the RSDT/XSDT 166 * in a common, more useable format. 167 */ 168 Status = AcpiTbParseRootTable (RsdpAddress); 169 return_ACPI_STATUS (Status); 170} 171 172ACPI_EXPORT_SYMBOL (AcpiInitializeTables) 173 174 175/******************************************************************************* 176 * 177 * FUNCTION: AcpiReallocateRootTable 178 * 179 * PARAMETERS: None 180 * 181 * RETURN: Status 182 * 183 * DESCRIPTION: Reallocate Root Table List into dynamic memory. Copies the 184 * root list from the previously provided scratch area. Should 185 * be called once dynamic memory allocation is available in the 186 * kernel 187 * 188 ******************************************************************************/ 189 190ACPI_STATUS 191AcpiReallocateRootTable ( 192 void) 193{ 194 ACPI_TABLE_DESC *Tables; 195 ACPI_SIZE NewSize; 196 ACPI_SIZE CurrentSize; 197 198 199 ACPI_FUNCTION_TRACE (AcpiReallocateRootTable); 200 201 202 /* 203 * Only reallocate the root table if the host provided a static buffer 204 * for the table array in the call to AcpiInitializeTables. 205 */ 206 if (AcpiGbl_RootTableList.Flags & ACPI_ROOT_ORIGIN_ALLOCATED) 207 { 208 return_ACPI_STATUS (AE_SUPPORT); 209 } 210 211 /* 212 * Get the current size of the root table and add the default 213 * increment to create the new table size. 214 */ 215 CurrentSize = (ACPI_SIZE) 216 AcpiGbl_RootTableList.CurrentTableCount * sizeof (ACPI_TABLE_DESC); 217 218 NewSize = CurrentSize + 219 (ACPI_ROOT_TABLE_SIZE_INCREMENT * sizeof (ACPI_TABLE_DESC)); 220 221 /* Create new array and copy the old array */ 222 223 Tables = ACPI_ALLOCATE_ZEROED (NewSize); 224 if (!Tables) 225 { 226 return_ACPI_STATUS (AE_NO_MEMORY); 227 } 228 229 ACPI_MEMCPY (Tables, AcpiGbl_RootTableList.Tables, CurrentSize); 230 231 /* 232 * Update the root table descriptor. The new size will be the current 233 * number of tables plus the increment, independent of the reserved 234 * size of the original table list. 235 */ 236 AcpiGbl_RootTableList.Tables = Tables; 237 AcpiGbl_RootTableList.MaxTableCount = 238 AcpiGbl_RootTableList.CurrentTableCount + ACPI_ROOT_TABLE_SIZE_INCREMENT; 239 AcpiGbl_RootTableList.Flags = 240 ACPI_ROOT_ORIGIN_ALLOCATED | ACPI_ROOT_ALLOW_RESIZE; 241 242 return_ACPI_STATUS (AE_OK); 243} 244 245ACPI_EXPORT_SYMBOL (AcpiReallocateRootTable) 246 247 248/******************************************************************************* 249 * 250 * FUNCTION: AcpiGetTableHeader 251 * 252 * PARAMETERS: Signature - ACPI signature of needed table 253 * Instance - Which instance (for SSDTs) 254 * OutTableHeader - The pointer to the table header to fill 255 * 256 * RETURN: Status and pointer to mapped table header 257 * 258 * DESCRIPTION: Finds an ACPI table header. 259 * 260 * NOTE: Caller is responsible in unmapping the header with 261 * AcpiOsUnmapMemory 262 * 263 ******************************************************************************/ 264 265ACPI_STATUS 266AcpiGetTableHeader ( 267 char *Signature, 268 UINT32 Instance, 269 ACPI_TABLE_HEADER *OutTableHeader) 270{ 271 UINT32 i; 272 UINT32 j; 273 ACPI_TABLE_HEADER *Header; 274 275 276 /* Parameter validation */ 277 278 if (!Signature || !OutTableHeader) 279 { 280 return (AE_BAD_PARAMETER); 281 } 282 283 /* Walk the root table list */ 284 285 for (i = 0, j = 0; i < AcpiGbl_RootTableList.CurrentTableCount; i++) 286 { 287 if (!ACPI_COMPARE_NAME (&(AcpiGbl_RootTableList.Tables[i].Signature), 288 Signature)) 289 { 290 continue; 291 } 292 293 if (++j < Instance) 294 { 295 continue; 296 } 297 298 if (!AcpiGbl_RootTableList.Tables[i].Pointer) 299 { 300 if ((AcpiGbl_RootTableList.Tables[i].Flags & 301 ACPI_TABLE_ORIGIN_MASK) == 302 ACPI_TABLE_ORIGIN_MAPPED) 303 { 304 Header = AcpiOsMapMemory ( 305 AcpiGbl_RootTableList.Tables[i].Address, 306 sizeof (ACPI_TABLE_HEADER)); 307 if (!Header) 308 { 309 return AE_NO_MEMORY; 310 } 311 312 ACPI_MEMCPY (OutTableHeader, Header, sizeof(ACPI_TABLE_HEADER)); 313 AcpiOsUnmapMemory (Header, sizeof(ACPI_TABLE_HEADER)); 314 } 315 else 316 { 317 return AE_NOT_FOUND; 318 } 319 } 320 else 321 { 322 ACPI_MEMCPY (OutTableHeader, 323 AcpiGbl_RootTableList.Tables[i].Pointer, 324 sizeof(ACPI_TABLE_HEADER)); 325 } 326 327 return (AE_OK); 328 } 329 330 return (AE_NOT_FOUND); 331} 332 333ACPI_EXPORT_SYMBOL (AcpiGetTableHeader) 334 335 336/******************************************************************************* 337 * 338 * FUNCTION: AcpiGetTable 339 * 340 * PARAMETERS: Signature - ACPI signature of needed table 341 * Instance - Which instance (for SSDTs) 342 * OutTable - Where the pointer to the table is returned 343 * 344 * RETURN: Status and pointer to table 345 * 346 * DESCRIPTION: Finds and verifies an ACPI table. 347 * 348 ******************************************************************************/ 349 350ACPI_STATUS 351AcpiGetTable ( 352 char *Signature, 353 UINT32 Instance, 354 ACPI_TABLE_HEADER **OutTable) 355{ 356 UINT32 i; 357 UINT32 j; 358 ACPI_STATUS Status; 359 360 361 /* Parameter validation */ 362 363 if (!Signature || !OutTable) 364 { 365 return (AE_BAD_PARAMETER); 366 } 367 368 /* Walk the root table list */ 369 370 for (i = 0, j = 0; i < AcpiGbl_RootTableList.CurrentTableCount; i++) 371 { 372 if (!ACPI_COMPARE_NAME (&(AcpiGbl_RootTableList.Tables[i].Signature), 373 Signature)) 374 { 375 continue; 376 } 377 378 if (++j < Instance) 379 { 380 continue; 381 } 382 383 Status = AcpiTbVerifyTable (&AcpiGbl_RootTableList.Tables[i]); 384 if (ACPI_SUCCESS (Status)) 385 { 386 *OutTable = AcpiGbl_RootTableList.Tables[i].Pointer; 387 } 388 389 return (Status); 390 } 391 392 return (AE_NOT_FOUND); 393} 394 395ACPI_EXPORT_SYMBOL (AcpiGetTable) 396 397 398/******************************************************************************* 399 * 400 * FUNCTION: AcpiGetTableByIndex 401 * 402 * PARAMETERS: TableIndex - Table index 403 * Table - Where the pointer to the table is returned 404 * 405 * RETURN: Status and pointer to the table 406 * 407 * DESCRIPTION: Obtain a table by an index into the global table list. 408 * 409 ******************************************************************************/ 410 411ACPI_STATUS 412AcpiGetTableByIndex ( 413 UINT32 TableIndex, 414 ACPI_TABLE_HEADER **Table) 415{ 416 ACPI_STATUS Status; 417 418 419 ACPI_FUNCTION_TRACE (AcpiGetTableByIndex); 420 421 422 /* Parameter validation */ 423 424 if (!Table) 425 { 426 return_ACPI_STATUS (AE_BAD_PARAMETER); 427 } 428 429 (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); 430 431 /* Validate index */ 432 433 if (TableIndex >= AcpiGbl_RootTableList.CurrentTableCount) 434 { 435 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 436 return_ACPI_STATUS (AE_BAD_PARAMETER); 437 } 438 439 if (!AcpiGbl_RootTableList.Tables[TableIndex].Pointer) 440 { 441 /* Table is not mapped, map it */ 442 443 Status = AcpiTbVerifyTable (&AcpiGbl_RootTableList.Tables[TableIndex]); 444 if (ACPI_FAILURE (Status)) 445 { 446 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 447 return_ACPI_STATUS (Status); 448 } 449 } 450 451 *Table = AcpiGbl_RootTableList.Tables[TableIndex].Pointer; 452 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 453 return_ACPI_STATUS (AE_OK); 454} 455 456ACPI_EXPORT_SYMBOL (AcpiGetTableByIndex) 457 458 459/******************************************************************************* 460 * 461 * FUNCTION: AcpiTbLoadNamespace 462 * 463 * PARAMETERS: None 464 * 465 * RETURN: Status 466 * 467 * DESCRIPTION: Load the namespace from the DSDT and all SSDTs/PSDTs found in 468 * the RSDT/XSDT. 469 * 470 ******************************************************************************/ 471 472static ACPI_STATUS 473AcpiTbLoadNamespace ( 474 void) 475{ 476 ACPI_STATUS Status; 477 UINT32 i; 478 ACPI_TABLE_HEADER *NewDsdt; 479 480 481 ACPI_FUNCTION_TRACE (TbLoadNamespace); 482 483 484 (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); 485 486 /* 487 * Load the namespace. The DSDT is required, but any SSDT and 488 * PSDT tables are optional. Verify the DSDT. 489 */ 490 if (!AcpiGbl_RootTableList.CurrentTableCount || 491 !ACPI_COMPARE_NAME ( 492 &(AcpiGbl_RootTableList.Tables[ACPI_TABLE_INDEX_DSDT].Signature), 493 ACPI_SIG_DSDT) || 494 ACPI_FAILURE (AcpiTbVerifyTable ( 495 &AcpiGbl_RootTableList.Tables[ACPI_TABLE_INDEX_DSDT]))) 496 { 497 Status = AE_NO_ACPI_TABLES; 498 goto UnlockAndExit; 499 } 500 501 /* 502 * Save the DSDT pointer for simple access. This is the mapped memory 503 * address. We must take care here because the address of the .Tables 504 * array can change dynamically as tables are loaded at run-time. Note: 505 * .Pointer field is not validated until after call to AcpiTbVerifyTable. 506 */ 507 AcpiGbl_DSDT = AcpiGbl_RootTableList.Tables[ACPI_TABLE_INDEX_DSDT].Pointer; 508 509 /* 510 * Optionally copy the entire DSDT to local memory (instead of simply 511 * mapping it.) There are some BIOSs that corrupt or replace the original 512 * DSDT, creating the need for this option. Default is FALSE, do not copy 513 * the DSDT. 514 */ 515 if (AcpiGbl_CopyDsdtLocally) 516 { 517 NewDsdt = AcpiTbCopyDsdt (ACPI_TABLE_INDEX_DSDT); 518 if (NewDsdt) 519 { 520 AcpiGbl_DSDT = NewDsdt; 521 } 522 } 523 524 /* 525 * Save the original DSDT header for detection of table corruption 526 * and/or replacement of the DSDT from outside the OS. 527 */ 528 ACPI_MEMCPY (&AcpiGbl_OriginalDsdtHeader, AcpiGbl_DSDT, 529 sizeof (ACPI_TABLE_HEADER)); 530 531 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 532 533 /* Load and parse tables */ 534 535 Status = AcpiNsLoadTable (ACPI_TABLE_INDEX_DSDT, AcpiGbl_RootNode); 536 if (ACPI_FAILURE (Status)) 537 { 538 return_ACPI_STATUS (Status); 539 } 540 541 /* Load any SSDT or PSDT tables. Note: Loop leaves tables locked */ 542 543 (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); 544 for (i = 2; i < AcpiGbl_RootTableList.CurrentTableCount; ++i) 545 { 546 if ((!ACPI_COMPARE_NAME (&(AcpiGbl_RootTableList.Tables[i].Signature), 547 ACPI_SIG_SSDT) && 548 !ACPI_COMPARE_NAME (&(AcpiGbl_RootTableList.Tables[i].Signature), 549 ACPI_SIG_PSDT)) || 550 ACPI_FAILURE (AcpiTbVerifyTable ( 551 &AcpiGbl_RootTableList.Tables[i]))) 552 { 553 continue; 554 } 555 556 /* Skip SSDT when DSDT is overriden */ 557 558 if (ACPI_COMPARE_NAME (&(AcpiGbl_RootTableList.Tables[i].Signature), 559 ACPI_SIG_SSDT) && 560 (AcpiGbl_RootTableList.Tables[ACPI_TABLE_INDEX_DSDT].Flags & 561 ACPI_TABLE_ORIGIN_OVERRIDE)) 562 { 563 continue; 564 } 565 566 /* Ignore errors while loading tables, get as many as possible */ 567 568 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 569 (void) AcpiNsLoadTable (i, AcpiGbl_RootNode); 570 (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); 571 } 572 573 ACPI_DEBUG_PRINT ((ACPI_DB_INIT, "ACPI Tables successfully acquired\n")); 574 575UnlockAndExit: 576 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 577 return_ACPI_STATUS (Status); 578} 579 580 581/******************************************************************************* 582 * 583 * FUNCTION: AcpiLoadTables 584 * 585 * PARAMETERS: None 586 * 587 * RETURN: Status 588 * 589 * DESCRIPTION: Load the ACPI tables from the RSDT/XSDT 590 * 591 ******************************************************************************/ 592 593ACPI_STATUS 594AcpiLoadTables ( 595 void) 596{ 597 ACPI_STATUS Status; 598 599 600 ACPI_FUNCTION_TRACE (AcpiLoadTables); 601 602 603 /* Load the namespace from the tables */ 604 605 Status = AcpiTbLoadNamespace (); 606 if (ACPI_FAILURE (Status)) 607 { 608 ACPI_EXCEPTION ((AE_INFO, Status, 609 "While loading namespace from ACPI tables")); 610 } 611 612 return_ACPI_STATUS (Status); 613} 614 615ACPI_EXPORT_SYMBOL (AcpiLoadTables) 616 617 618/******************************************************************************* 619 * 620 * FUNCTION: AcpiInstallTableHandler 621 * 622 * PARAMETERS: Handler - Table event handler 623 * Context - Value passed to the handler on each event 624 * 625 * RETURN: Status 626 * 627 * DESCRIPTION: Install table event handler 628 * 629 ******************************************************************************/ 630 631ACPI_STATUS 632AcpiInstallTableHandler ( 633 ACPI_TABLE_HANDLER Handler, 634 void *Context) 635{ 636 ACPI_STATUS Status; 637 638 639 ACPI_FUNCTION_TRACE (AcpiInstallTableHandler); 640 641 642 if (!Handler) 643 { 644 return_ACPI_STATUS (AE_BAD_PARAMETER); 645 } 646 647 Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS); 648 if (ACPI_FAILURE (Status)) 649 { 650 return_ACPI_STATUS (Status); 651 } 652 653 /* Don't allow more than one handler */ 654 655 if (AcpiGbl_TableHandler) 656 { 657 Status = AE_ALREADY_EXISTS; 658 goto Cleanup; 659 } 660 661 /* Install the handler */ 662 663 AcpiGbl_TableHandler = Handler; 664 AcpiGbl_TableHandlerContext = Context; 665 666Cleanup: 667 (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS); 668 return_ACPI_STATUS (Status); 669} 670 671ACPI_EXPORT_SYMBOL (AcpiInstallTableHandler) 672 673 674/******************************************************************************* 675 * 676 * FUNCTION: AcpiRemoveTableHandler 677 * 678 * PARAMETERS: Handler - Table event handler that was installed 679 * previously. 680 * 681 * RETURN: Status 682 * 683 * DESCRIPTION: Remove table event handler 684 * 685 ******************************************************************************/ 686 687ACPI_STATUS 688AcpiRemoveTableHandler ( 689 ACPI_TABLE_HANDLER Handler) 690{ 691 ACPI_STATUS Status; 692 693 694 ACPI_FUNCTION_TRACE (AcpiRemoveTableHandler); 695 696 697 Status = AcpiUtAcquireMutex (ACPI_MTX_EVENTS); 698 if (ACPI_FAILURE (Status)) 699 { 700 return_ACPI_STATUS (Status); 701 } 702 703 /* Make sure that the installed handler is the same */ 704 705 if (!Handler || 706 Handler != AcpiGbl_TableHandler) 707 { 708 Status = AE_BAD_PARAMETER; 709 goto Cleanup; 710 } 711 712 /* Remove the handler */ 713 714 AcpiGbl_TableHandler = NULL; 715 716Cleanup: 717 (void) AcpiUtReleaseMutex (ACPI_MTX_EVENTS); 718 return_ACPI_STATUS (Status); 719} 720 721ACPI_EXPORT_SYMBOL (AcpiRemoveTableHandler) 722 723