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 45#define __TBINSTAL_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 53#define _COMPONENT ACPI_TABLES 54 ACPI_MODULE_NAME ("tbinstal") 55 56 57/****************************************************************************** 58 * 59 * FUNCTION: AcpiTbVerifyTable 60 * 61 * PARAMETERS: TableDesc - table 62 * 63 * RETURN: Status 64 * 65 * DESCRIPTION: this function is called to verify and map table 66 * 67 *****************************************************************************/ 68 69ACPI_STATUS 70AcpiTbVerifyTable ( 71 ACPI_TABLE_DESC *TableDesc) 72{ 73 ACPI_STATUS Status = AE_OK; 74 75 76 ACPI_FUNCTION_TRACE (TbVerifyTable); 77 78 79 /* Map the table if necessary */ 80 81 if (!TableDesc->Pointer) 82 { 83 if ((TableDesc->Flags & ACPI_TABLE_ORIGIN_MASK) == 84 ACPI_TABLE_ORIGIN_MAPPED) 85 { 86 TableDesc->Pointer = AcpiOsMapMemory ( 87 TableDesc->Address, TableDesc->Length); 88 } 89 90 if (!TableDesc->Pointer) 91 { 92 return_ACPI_STATUS (AE_NO_MEMORY); 93 } 94 } 95 96 /* FACS is the odd table, has no standard ACPI header and no checksum */ 97 98 if (!ACPI_COMPARE_NAME (&TableDesc->Signature, ACPI_SIG_FACS)) 99 { 100 /* Always calculate checksum, ignore bad checksum if requested */ 101 102 Status = AcpiTbVerifyChecksum (TableDesc->Pointer, TableDesc->Length); 103 } 104 105 return_ACPI_STATUS (Status); 106} 107 108 109/******************************************************************************* 110 * 111 * FUNCTION: AcpiTbAddTable 112 * 113 * PARAMETERS: TableDesc - Table descriptor 114 * TableIndex - Where the table index is returned 115 * 116 * RETURN: Status 117 * 118 * DESCRIPTION: This function is called to add an ACPI table. It is used to 119 * dynamically load tables via the Load and LoadTable AML 120 * operators. 121 * 122 ******************************************************************************/ 123 124ACPI_STATUS 125AcpiTbAddTable ( 126 ACPI_TABLE_DESC *TableDesc, 127 UINT32 *TableIndex) 128{ 129 UINT32 i; 130 ACPI_STATUS Status = AE_OK; 131 ACPI_TABLE_HEADER *OverrideTable = NULL; 132 133 134 ACPI_FUNCTION_TRACE (TbAddTable); 135 136 137 if (!TableDesc->Pointer) 138 { 139 Status = AcpiTbVerifyTable (TableDesc); 140 if (ACPI_FAILURE (Status) || !TableDesc->Pointer) 141 { 142 return_ACPI_STATUS (Status); 143 } 144 } 145 146 /*
| 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 45#define __TBINSTAL_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 53#define _COMPONENT ACPI_TABLES 54 ACPI_MODULE_NAME ("tbinstal") 55 56 57/****************************************************************************** 58 * 59 * FUNCTION: AcpiTbVerifyTable 60 * 61 * PARAMETERS: TableDesc - table 62 * 63 * RETURN: Status 64 * 65 * DESCRIPTION: this function is called to verify and map table 66 * 67 *****************************************************************************/ 68 69ACPI_STATUS 70AcpiTbVerifyTable ( 71 ACPI_TABLE_DESC *TableDesc) 72{ 73 ACPI_STATUS Status = AE_OK; 74 75 76 ACPI_FUNCTION_TRACE (TbVerifyTable); 77 78 79 /* Map the table if necessary */ 80 81 if (!TableDesc->Pointer) 82 { 83 if ((TableDesc->Flags & ACPI_TABLE_ORIGIN_MASK) == 84 ACPI_TABLE_ORIGIN_MAPPED) 85 { 86 TableDesc->Pointer = AcpiOsMapMemory ( 87 TableDesc->Address, TableDesc->Length); 88 } 89 90 if (!TableDesc->Pointer) 91 { 92 return_ACPI_STATUS (AE_NO_MEMORY); 93 } 94 } 95 96 /* FACS is the odd table, has no standard ACPI header and no checksum */ 97 98 if (!ACPI_COMPARE_NAME (&TableDesc->Signature, ACPI_SIG_FACS)) 99 { 100 /* Always calculate checksum, ignore bad checksum if requested */ 101 102 Status = AcpiTbVerifyChecksum (TableDesc->Pointer, TableDesc->Length); 103 } 104 105 return_ACPI_STATUS (Status); 106} 107 108 109/******************************************************************************* 110 * 111 * FUNCTION: AcpiTbAddTable 112 * 113 * PARAMETERS: TableDesc - Table descriptor 114 * TableIndex - Where the table index is returned 115 * 116 * RETURN: Status 117 * 118 * DESCRIPTION: This function is called to add an ACPI table. It is used to 119 * dynamically load tables via the Load and LoadTable AML 120 * operators. 121 * 122 ******************************************************************************/ 123 124ACPI_STATUS 125AcpiTbAddTable ( 126 ACPI_TABLE_DESC *TableDesc, 127 UINT32 *TableIndex) 128{ 129 UINT32 i; 130 ACPI_STATUS Status = AE_OK; 131 ACPI_TABLE_HEADER *OverrideTable = NULL; 132 133 134 ACPI_FUNCTION_TRACE (TbAddTable); 135 136 137 if (!TableDesc->Pointer) 138 { 139 Status = AcpiTbVerifyTable (TableDesc); 140 if (ACPI_FAILURE (Status) || !TableDesc->Pointer) 141 { 142 return_ACPI_STATUS (Status); 143 } 144 } 145 146 /*
|
147 * Originally, we checked the table signature for "SSDT" or "PSDT" here. 148 * Next, we added support for OEMx tables, signature "OEM". 149 * Valid tables were encountered with a null signature, so we've just 150 * given up on validating the signature, since it seems to be a waste 151 * of code. The original code was removed (05/2008).
| 147 * Validate the incoming table signature. 148 * 149 * 1) Originally, we checked the table signature for "SSDT" or "PSDT". 150 * 2) We added support for OEMx tables, signature "OEM". 151 * 3) Valid tables were encountered with a null signature, so we just 152 * gave up on validating the signature, (05/2008). 153 * 4) We encountered non-AML tables such as the MADT, which caused 154 * interpreter errors and kernel faults. So now, we once again allow 155 * only "SSDT", "OEMx", and now, also a null signature. (05/2011).
|
152 */
| 156 */
|
| 157 if ((TableDesc->Pointer->Signature[0] != 0x00) && 158 (!ACPI_COMPARE_NAME (TableDesc->Pointer->Signature, ACPI_SIG_SSDT)) && 159 (ACPI_STRNCMP (TableDesc->Pointer->Signature, "OEM", 3))) 160 { 161 ACPI_ERROR ((AE_INFO, 162 "Table has invalid signature [%4.4s] (0x%8.8X), must be SSDT or OEMx", 163 AcpiUtValidAcpiName (*(UINT32 *) TableDesc->Pointer->Signature) ? 164 TableDesc->Pointer->Signature : "????", 165 *(UINT32 *) TableDesc->Pointer->Signature));
|
153
| 166
|
| 167 return_ACPI_STATUS (AE_BAD_SIGNATURE); 168 } 169
|
154 (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); 155 156 /* Check if table is already registered */ 157 158 for (i = 0; i < AcpiGbl_RootTableList.CurrentTableCount; ++i) 159 { 160 if (!AcpiGbl_RootTableList.Tables[i].Pointer) 161 { 162 Status = AcpiTbVerifyTable (&AcpiGbl_RootTableList.Tables[i]); 163 if (ACPI_FAILURE (Status) || 164 !AcpiGbl_RootTableList.Tables[i].Pointer) 165 { 166 continue; 167 } 168 } 169 170 /* 171 * Check for a table match on the entire table length, 172 * not just the header. 173 */ 174 if (TableDesc->Length != AcpiGbl_RootTableList.Tables[i].Length) 175 { 176 continue; 177 } 178 179 if (ACPI_MEMCMP (TableDesc->Pointer, 180 AcpiGbl_RootTableList.Tables[i].Pointer, 181 AcpiGbl_RootTableList.Tables[i].Length)) 182 { 183 continue; 184 } 185 186 /* 187 * Note: the current mechanism does not unregister a table if it is 188 * dynamically unloaded. The related namespace entries are deleted, 189 * but the table remains in the root table list. 190 * 191 * The assumption here is that the number of different tables that 192 * will be loaded is actually small, and there is minimal overhead 193 * in just keeping the table in case it is needed again. 194 * 195 * If this assumption changes in the future (perhaps on large 196 * machines with many table load/unload operations), tables will 197 * need to be unregistered when they are unloaded, and slots in the 198 * root table list should be reused when empty. 199 */ 200 201 /* 202 * Table is already registered. 203 * We can delete the table that was passed as a parameter. 204 */ 205 AcpiTbDeleteTable (TableDesc); 206 *TableIndex = i; 207 208 if (AcpiGbl_RootTableList.Tables[i].Flags & ACPI_TABLE_IS_LOADED) 209 { 210 /* Table is still loaded, this is an error */ 211 212 Status = AE_ALREADY_EXISTS; 213 goto Release; 214 } 215 else 216 { 217 /* Table was unloaded, allow it to be reloaded */ 218 219 TableDesc->Pointer = AcpiGbl_RootTableList.Tables[i].Pointer; 220 TableDesc->Address = AcpiGbl_RootTableList.Tables[i].Address; 221 Status = AE_OK; 222 goto PrintHeader; 223 } 224 } 225 226 /* 227 * ACPI Table Override: 228 * Allow the host to override dynamically loaded tables. 229 */ 230 Status = AcpiOsTableOverride (TableDesc->Pointer, &OverrideTable); 231 if (ACPI_SUCCESS (Status) && OverrideTable) 232 { 233 ACPI_INFO ((AE_INFO, 234 "%4.4s @ 0x%p Table override, replaced with:", 235 TableDesc->Pointer->Signature, 236 ACPI_CAST_PTR (void, TableDesc->Address))); 237 238 /* We can delete the table that was passed as a parameter */ 239 240 AcpiTbDeleteTable (TableDesc); 241 242 /* Setup descriptor for the new table */ 243 244 TableDesc->Address = ACPI_PTR_TO_PHYSADDR (OverrideTable); 245 TableDesc->Pointer = OverrideTable; 246 TableDesc->Length = OverrideTable->Length; 247 TableDesc->Flags = ACPI_TABLE_ORIGIN_OVERRIDE; 248 } 249 250 /* Add the table to the global root table list */ 251 252 Status = AcpiTbStoreTable (TableDesc->Address, TableDesc->Pointer, 253 TableDesc->Length, TableDesc->Flags, TableIndex); 254 if (ACPI_FAILURE (Status)) 255 { 256 goto Release; 257 } 258 259PrintHeader: 260 AcpiTbPrintTableHeader (TableDesc->Address, TableDesc->Pointer); 261 262Release: 263 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 264 return_ACPI_STATUS (Status); 265} 266 267 268/******************************************************************************* 269 * 270 * FUNCTION: AcpiTbResizeRootTableList 271 * 272 * PARAMETERS: None 273 * 274 * RETURN: Status 275 * 276 * DESCRIPTION: Expand the size of global table array 277 * 278 ******************************************************************************/ 279 280ACPI_STATUS 281AcpiTbResizeRootTableList ( 282 void) 283{ 284 ACPI_TABLE_DESC *Tables; 285 286 287 ACPI_FUNCTION_TRACE (TbResizeRootTableList); 288 289 290 /* AllowResize flag is a parameter to AcpiInitializeTables */ 291 292 if (!(AcpiGbl_RootTableList.Flags & ACPI_ROOT_ALLOW_RESIZE)) 293 { 294 ACPI_ERROR ((AE_INFO, "Resize of Root Table Array is not allowed")); 295 return_ACPI_STATUS (AE_SUPPORT); 296 } 297 298 /* Increase the Table Array size */ 299 300 Tables = ACPI_ALLOCATE_ZEROED ( 301 ((ACPI_SIZE) AcpiGbl_RootTableList.MaxTableCount + 302 ACPI_ROOT_TABLE_SIZE_INCREMENT) * 303 sizeof (ACPI_TABLE_DESC)); 304 if (!Tables) 305 { 306 ACPI_ERROR ((AE_INFO, "Could not allocate new root table array")); 307 return_ACPI_STATUS (AE_NO_MEMORY); 308 } 309 310 /* Copy and free the previous table array */ 311 312 if (AcpiGbl_RootTableList.Tables) 313 { 314 ACPI_MEMCPY (Tables, AcpiGbl_RootTableList.Tables, 315 (ACPI_SIZE) AcpiGbl_RootTableList.MaxTableCount * sizeof (ACPI_TABLE_DESC)); 316 317 if (AcpiGbl_RootTableList.Flags & ACPI_ROOT_ORIGIN_ALLOCATED) 318 { 319 ACPI_FREE (AcpiGbl_RootTableList.Tables); 320 } 321 } 322 323 AcpiGbl_RootTableList.Tables = Tables; 324 AcpiGbl_RootTableList.MaxTableCount += ACPI_ROOT_TABLE_SIZE_INCREMENT; 325 AcpiGbl_RootTableList.Flags |= (UINT8) ACPI_ROOT_ORIGIN_ALLOCATED; 326 327 return_ACPI_STATUS (AE_OK); 328} 329 330 331/******************************************************************************* 332 * 333 * FUNCTION: AcpiTbStoreTable 334 * 335 * PARAMETERS: Address - Table address 336 * Table - Table header 337 * Length - Table length 338 * Flags - flags 339 * 340 * RETURN: Status and table index. 341 * 342 * DESCRIPTION: Add an ACPI table to the global table list 343 * 344 ******************************************************************************/ 345 346ACPI_STATUS 347AcpiTbStoreTable ( 348 ACPI_PHYSICAL_ADDRESS Address, 349 ACPI_TABLE_HEADER *Table, 350 UINT32 Length, 351 UINT8 Flags, 352 UINT32 *TableIndex) 353{ 354 ACPI_STATUS Status; 355 ACPI_TABLE_DESC *NewTable; 356 357 358 /* Ensure that there is room for the table in the Root Table List */ 359 360 if (AcpiGbl_RootTableList.CurrentTableCount >= 361 AcpiGbl_RootTableList.MaxTableCount) 362 { 363 Status = AcpiTbResizeRootTableList(); 364 if (ACPI_FAILURE (Status)) 365 { 366 return (Status); 367 } 368 } 369 370 NewTable = &AcpiGbl_RootTableList.Tables[AcpiGbl_RootTableList.CurrentTableCount]; 371 372 /* Initialize added table */ 373 374 NewTable->Address = Address; 375 NewTable->Pointer = Table; 376 NewTable->Length = Length; 377 NewTable->OwnerId = 0; 378 NewTable->Flags = Flags; 379 380 ACPI_MOVE_32_TO_32 (&NewTable->Signature, Table->Signature); 381 382 *TableIndex = AcpiGbl_RootTableList.CurrentTableCount; 383 AcpiGbl_RootTableList.CurrentTableCount++; 384 return (AE_OK); 385} 386 387 388/******************************************************************************* 389 * 390 * FUNCTION: AcpiTbDeleteTable 391 * 392 * PARAMETERS: TableIndex - Table index 393 * 394 * RETURN: None 395 * 396 * DESCRIPTION: Delete one internal ACPI table 397 * 398 ******************************************************************************/ 399 400void 401AcpiTbDeleteTable ( 402 ACPI_TABLE_DESC *TableDesc) 403{ 404 405 /* Table must be mapped or allocated */ 406 407 if (!TableDesc->Pointer) 408 { 409 return; 410 } 411 412 switch (TableDesc->Flags & ACPI_TABLE_ORIGIN_MASK) 413 { 414 case ACPI_TABLE_ORIGIN_MAPPED: 415 AcpiOsUnmapMemory (TableDesc->Pointer, TableDesc->Length); 416 break; 417 418 case ACPI_TABLE_ORIGIN_ALLOCATED: 419 ACPI_FREE (TableDesc->Pointer); 420 break; 421 422 default: 423 break; 424 } 425 426 TableDesc->Pointer = NULL; 427} 428 429 430/******************************************************************************* 431 * 432 * FUNCTION: AcpiTbTerminate 433 * 434 * PARAMETERS: None 435 * 436 * RETURN: None 437 * 438 * DESCRIPTION: Delete all internal ACPI tables 439 * 440 ******************************************************************************/ 441 442void 443AcpiTbTerminate ( 444 void) 445{ 446 UINT32 i; 447 448 449 ACPI_FUNCTION_TRACE (TbTerminate); 450 451 452 (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); 453 454 /* Delete the individual tables */ 455 456 for (i = 0; i < AcpiGbl_RootTableList.CurrentTableCount; i++) 457 { 458 AcpiTbDeleteTable (&AcpiGbl_RootTableList.Tables[i]); 459 } 460 461 /* 462 * Delete the root table array if allocated locally. Array cannot be 463 * mapped, so we don't need to check for that flag. 464 */ 465 if (AcpiGbl_RootTableList.Flags & ACPI_ROOT_ORIGIN_ALLOCATED) 466 { 467 ACPI_FREE (AcpiGbl_RootTableList.Tables); 468 } 469 470 AcpiGbl_RootTableList.Tables = NULL; 471 AcpiGbl_RootTableList.Flags = 0; 472 AcpiGbl_RootTableList.CurrentTableCount = 0; 473 474 ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "ACPI Tables freed\n")); 475 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 476} 477 478 479/******************************************************************************* 480 * 481 * FUNCTION: AcpiTbDeleteNamespaceByOwner 482 * 483 * PARAMETERS: TableIndex - Table index 484 * 485 * RETURN: Status 486 * 487 * DESCRIPTION: Delete all namespace objects created when this table was loaded. 488 * 489 ******************************************************************************/ 490 491ACPI_STATUS 492AcpiTbDeleteNamespaceByOwner ( 493 UINT32 TableIndex) 494{ 495 ACPI_OWNER_ID OwnerId; 496 ACPI_STATUS Status; 497 498 499 ACPI_FUNCTION_TRACE (TbDeleteNamespaceByOwner); 500 501 502 Status = AcpiUtAcquireMutex (ACPI_MTX_TABLES); 503 if (ACPI_FAILURE (Status)) 504 { 505 return_ACPI_STATUS (Status); 506 } 507 508 if (TableIndex >= AcpiGbl_RootTableList.CurrentTableCount) 509 { 510 /* The table index does not exist */ 511 512 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 513 return_ACPI_STATUS (AE_NOT_EXIST); 514 } 515 516 /* Get the owner ID for this table, used to delete namespace nodes */ 517 518 OwnerId = AcpiGbl_RootTableList.Tables[TableIndex].OwnerId; 519 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 520 521 /* 522 * Need to acquire the namespace writer lock to prevent interference 523 * with any concurrent namespace walks. The interpreter must be 524 * released during the deletion since the acquisition of the deletion 525 * lock may block, and also since the execution of a namespace walk 526 * must be allowed to use the interpreter. 527 */ 528 (void) AcpiUtReleaseMutex (ACPI_MTX_INTERPRETER); 529 Status = AcpiUtAcquireWriteLock (&AcpiGbl_NamespaceRwLock); 530 531 AcpiNsDeleteNamespaceByOwner (OwnerId); 532 if (ACPI_FAILURE (Status)) 533 { 534 return_ACPI_STATUS (Status); 535 } 536 537 AcpiUtReleaseWriteLock (&AcpiGbl_NamespaceRwLock); 538 539 Status = AcpiUtAcquireMutex (ACPI_MTX_INTERPRETER); 540 return_ACPI_STATUS (Status); 541} 542 543 544/******************************************************************************* 545 * 546 * FUNCTION: AcpiTbAllocateOwnerId 547 * 548 * PARAMETERS: TableIndex - Table index 549 * 550 * RETURN: Status 551 * 552 * DESCRIPTION: Allocates OwnerId in TableDesc 553 * 554 ******************************************************************************/ 555 556ACPI_STATUS 557AcpiTbAllocateOwnerId ( 558 UINT32 TableIndex) 559{ 560 ACPI_STATUS Status = AE_BAD_PARAMETER; 561 562 563 ACPI_FUNCTION_TRACE (TbAllocateOwnerId); 564 565 566 (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); 567 if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount) 568 { 569 Status = AcpiUtAllocateOwnerId 570 (&(AcpiGbl_RootTableList.Tables[TableIndex].OwnerId)); 571 } 572 573 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 574 return_ACPI_STATUS (Status); 575} 576 577 578/******************************************************************************* 579 * 580 * FUNCTION: AcpiTbReleaseOwnerId 581 * 582 * PARAMETERS: TableIndex - Table index 583 * 584 * RETURN: Status 585 * 586 * DESCRIPTION: Releases OwnerId in TableDesc 587 * 588 ******************************************************************************/ 589 590ACPI_STATUS 591AcpiTbReleaseOwnerId ( 592 UINT32 TableIndex) 593{ 594 ACPI_STATUS Status = AE_BAD_PARAMETER; 595 596 597 ACPI_FUNCTION_TRACE (TbReleaseOwnerId); 598 599 600 (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); 601 if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount) 602 { 603 AcpiUtReleaseOwnerId ( 604 &(AcpiGbl_RootTableList.Tables[TableIndex].OwnerId)); 605 Status = AE_OK; 606 } 607 608 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 609 return_ACPI_STATUS (Status); 610} 611 612 613/******************************************************************************* 614 * 615 * FUNCTION: AcpiTbGetOwnerId 616 * 617 * PARAMETERS: TableIndex - Table index 618 * OwnerId - Where the table OwnerId is returned 619 * 620 * RETURN: Status 621 * 622 * DESCRIPTION: returns OwnerId for the ACPI table 623 * 624 ******************************************************************************/ 625 626ACPI_STATUS 627AcpiTbGetOwnerId ( 628 UINT32 TableIndex, 629 ACPI_OWNER_ID *OwnerId) 630{ 631 ACPI_STATUS Status = AE_BAD_PARAMETER; 632 633 634 ACPI_FUNCTION_TRACE (TbGetOwnerId); 635 636 637 (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); 638 if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount) 639 { 640 *OwnerId = AcpiGbl_RootTableList.Tables[TableIndex].OwnerId; 641 Status = AE_OK; 642 } 643 644 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 645 return_ACPI_STATUS (Status); 646} 647 648 649/******************************************************************************* 650 * 651 * FUNCTION: AcpiTbIsTableLoaded 652 * 653 * PARAMETERS: TableIndex - Table index 654 * 655 * RETURN: Table Loaded Flag 656 * 657 ******************************************************************************/ 658 659BOOLEAN 660AcpiTbIsTableLoaded ( 661 UINT32 TableIndex) 662{ 663 BOOLEAN IsLoaded = FALSE; 664 665 666 (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); 667 if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount) 668 { 669 IsLoaded = (BOOLEAN) 670 (AcpiGbl_RootTableList.Tables[TableIndex].Flags & 671 ACPI_TABLE_IS_LOADED); 672 } 673 674 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 675 return (IsLoaded); 676} 677 678 679/******************************************************************************* 680 * 681 * FUNCTION: AcpiTbSetTableLoadedFlag 682 * 683 * PARAMETERS: TableIndex - Table index 684 * IsLoaded - TRUE if table is loaded, FALSE otherwise 685 * 686 * RETURN: None 687 * 688 * DESCRIPTION: Sets the table loaded flag to either TRUE or FALSE. 689 * 690 ******************************************************************************/ 691 692void 693AcpiTbSetTableLoadedFlag ( 694 UINT32 TableIndex, 695 BOOLEAN IsLoaded) 696{ 697 698 (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); 699 if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount) 700 { 701 if (IsLoaded) 702 { 703 AcpiGbl_RootTableList.Tables[TableIndex].Flags |= 704 ACPI_TABLE_IS_LOADED; 705 } 706 else 707 { 708 AcpiGbl_RootTableList.Tables[TableIndex].Flags &= 709 ~ACPI_TABLE_IS_LOADED; 710 } 711 } 712 713 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 714} 715
| 170 (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); 171 172 /* Check if table is already registered */ 173 174 for (i = 0; i < AcpiGbl_RootTableList.CurrentTableCount; ++i) 175 { 176 if (!AcpiGbl_RootTableList.Tables[i].Pointer) 177 { 178 Status = AcpiTbVerifyTable (&AcpiGbl_RootTableList.Tables[i]); 179 if (ACPI_FAILURE (Status) || 180 !AcpiGbl_RootTableList.Tables[i].Pointer) 181 { 182 continue; 183 } 184 } 185 186 /* 187 * Check for a table match on the entire table length, 188 * not just the header. 189 */ 190 if (TableDesc->Length != AcpiGbl_RootTableList.Tables[i].Length) 191 { 192 continue; 193 } 194 195 if (ACPI_MEMCMP (TableDesc->Pointer, 196 AcpiGbl_RootTableList.Tables[i].Pointer, 197 AcpiGbl_RootTableList.Tables[i].Length)) 198 { 199 continue; 200 } 201 202 /* 203 * Note: the current mechanism does not unregister a table if it is 204 * dynamically unloaded. The related namespace entries are deleted, 205 * but the table remains in the root table list. 206 * 207 * The assumption here is that the number of different tables that 208 * will be loaded is actually small, and there is minimal overhead 209 * in just keeping the table in case it is needed again. 210 * 211 * If this assumption changes in the future (perhaps on large 212 * machines with many table load/unload operations), tables will 213 * need to be unregistered when they are unloaded, and slots in the 214 * root table list should be reused when empty. 215 */ 216 217 /* 218 * Table is already registered. 219 * We can delete the table that was passed as a parameter. 220 */ 221 AcpiTbDeleteTable (TableDesc); 222 *TableIndex = i; 223 224 if (AcpiGbl_RootTableList.Tables[i].Flags & ACPI_TABLE_IS_LOADED) 225 { 226 /* Table is still loaded, this is an error */ 227 228 Status = AE_ALREADY_EXISTS; 229 goto Release; 230 } 231 else 232 { 233 /* Table was unloaded, allow it to be reloaded */ 234 235 TableDesc->Pointer = AcpiGbl_RootTableList.Tables[i].Pointer; 236 TableDesc->Address = AcpiGbl_RootTableList.Tables[i].Address; 237 Status = AE_OK; 238 goto PrintHeader; 239 } 240 } 241 242 /* 243 * ACPI Table Override: 244 * Allow the host to override dynamically loaded tables. 245 */ 246 Status = AcpiOsTableOverride (TableDesc->Pointer, &OverrideTable); 247 if (ACPI_SUCCESS (Status) && OverrideTable) 248 { 249 ACPI_INFO ((AE_INFO, 250 "%4.4s @ 0x%p Table override, replaced with:", 251 TableDesc->Pointer->Signature, 252 ACPI_CAST_PTR (void, TableDesc->Address))); 253 254 /* We can delete the table that was passed as a parameter */ 255 256 AcpiTbDeleteTable (TableDesc); 257 258 /* Setup descriptor for the new table */ 259 260 TableDesc->Address = ACPI_PTR_TO_PHYSADDR (OverrideTable); 261 TableDesc->Pointer = OverrideTable; 262 TableDesc->Length = OverrideTable->Length; 263 TableDesc->Flags = ACPI_TABLE_ORIGIN_OVERRIDE; 264 } 265 266 /* Add the table to the global root table list */ 267 268 Status = AcpiTbStoreTable (TableDesc->Address, TableDesc->Pointer, 269 TableDesc->Length, TableDesc->Flags, TableIndex); 270 if (ACPI_FAILURE (Status)) 271 { 272 goto Release; 273 } 274 275PrintHeader: 276 AcpiTbPrintTableHeader (TableDesc->Address, TableDesc->Pointer); 277 278Release: 279 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 280 return_ACPI_STATUS (Status); 281} 282 283 284/******************************************************************************* 285 * 286 * FUNCTION: AcpiTbResizeRootTableList 287 * 288 * PARAMETERS: None 289 * 290 * RETURN: Status 291 * 292 * DESCRIPTION: Expand the size of global table array 293 * 294 ******************************************************************************/ 295 296ACPI_STATUS 297AcpiTbResizeRootTableList ( 298 void) 299{ 300 ACPI_TABLE_DESC *Tables; 301 302 303 ACPI_FUNCTION_TRACE (TbResizeRootTableList); 304 305 306 /* AllowResize flag is a parameter to AcpiInitializeTables */ 307 308 if (!(AcpiGbl_RootTableList.Flags & ACPI_ROOT_ALLOW_RESIZE)) 309 { 310 ACPI_ERROR ((AE_INFO, "Resize of Root Table Array is not allowed")); 311 return_ACPI_STATUS (AE_SUPPORT); 312 } 313 314 /* Increase the Table Array size */ 315 316 Tables = ACPI_ALLOCATE_ZEROED ( 317 ((ACPI_SIZE) AcpiGbl_RootTableList.MaxTableCount + 318 ACPI_ROOT_TABLE_SIZE_INCREMENT) * 319 sizeof (ACPI_TABLE_DESC)); 320 if (!Tables) 321 { 322 ACPI_ERROR ((AE_INFO, "Could not allocate new root table array")); 323 return_ACPI_STATUS (AE_NO_MEMORY); 324 } 325 326 /* Copy and free the previous table array */ 327 328 if (AcpiGbl_RootTableList.Tables) 329 { 330 ACPI_MEMCPY (Tables, AcpiGbl_RootTableList.Tables, 331 (ACPI_SIZE) AcpiGbl_RootTableList.MaxTableCount * sizeof (ACPI_TABLE_DESC)); 332 333 if (AcpiGbl_RootTableList.Flags & ACPI_ROOT_ORIGIN_ALLOCATED) 334 { 335 ACPI_FREE (AcpiGbl_RootTableList.Tables); 336 } 337 } 338 339 AcpiGbl_RootTableList.Tables = Tables; 340 AcpiGbl_RootTableList.MaxTableCount += ACPI_ROOT_TABLE_SIZE_INCREMENT; 341 AcpiGbl_RootTableList.Flags |= (UINT8) ACPI_ROOT_ORIGIN_ALLOCATED; 342 343 return_ACPI_STATUS (AE_OK); 344} 345 346 347/******************************************************************************* 348 * 349 * FUNCTION: AcpiTbStoreTable 350 * 351 * PARAMETERS: Address - Table address 352 * Table - Table header 353 * Length - Table length 354 * Flags - flags 355 * 356 * RETURN: Status and table index. 357 * 358 * DESCRIPTION: Add an ACPI table to the global table list 359 * 360 ******************************************************************************/ 361 362ACPI_STATUS 363AcpiTbStoreTable ( 364 ACPI_PHYSICAL_ADDRESS Address, 365 ACPI_TABLE_HEADER *Table, 366 UINT32 Length, 367 UINT8 Flags, 368 UINT32 *TableIndex) 369{ 370 ACPI_STATUS Status; 371 ACPI_TABLE_DESC *NewTable; 372 373 374 /* Ensure that there is room for the table in the Root Table List */ 375 376 if (AcpiGbl_RootTableList.CurrentTableCount >= 377 AcpiGbl_RootTableList.MaxTableCount) 378 { 379 Status = AcpiTbResizeRootTableList(); 380 if (ACPI_FAILURE (Status)) 381 { 382 return (Status); 383 } 384 } 385 386 NewTable = &AcpiGbl_RootTableList.Tables[AcpiGbl_RootTableList.CurrentTableCount]; 387 388 /* Initialize added table */ 389 390 NewTable->Address = Address; 391 NewTable->Pointer = Table; 392 NewTable->Length = Length; 393 NewTable->OwnerId = 0; 394 NewTable->Flags = Flags; 395 396 ACPI_MOVE_32_TO_32 (&NewTable->Signature, Table->Signature); 397 398 *TableIndex = AcpiGbl_RootTableList.CurrentTableCount; 399 AcpiGbl_RootTableList.CurrentTableCount++; 400 return (AE_OK); 401} 402 403 404/******************************************************************************* 405 * 406 * FUNCTION: AcpiTbDeleteTable 407 * 408 * PARAMETERS: TableIndex - Table index 409 * 410 * RETURN: None 411 * 412 * DESCRIPTION: Delete one internal ACPI table 413 * 414 ******************************************************************************/ 415 416void 417AcpiTbDeleteTable ( 418 ACPI_TABLE_DESC *TableDesc) 419{ 420 421 /* Table must be mapped or allocated */ 422 423 if (!TableDesc->Pointer) 424 { 425 return; 426 } 427 428 switch (TableDesc->Flags & ACPI_TABLE_ORIGIN_MASK) 429 { 430 case ACPI_TABLE_ORIGIN_MAPPED: 431 AcpiOsUnmapMemory (TableDesc->Pointer, TableDesc->Length); 432 break; 433 434 case ACPI_TABLE_ORIGIN_ALLOCATED: 435 ACPI_FREE (TableDesc->Pointer); 436 break; 437 438 default: 439 break; 440 } 441 442 TableDesc->Pointer = NULL; 443} 444 445 446/******************************************************************************* 447 * 448 * FUNCTION: AcpiTbTerminate 449 * 450 * PARAMETERS: None 451 * 452 * RETURN: None 453 * 454 * DESCRIPTION: Delete all internal ACPI tables 455 * 456 ******************************************************************************/ 457 458void 459AcpiTbTerminate ( 460 void) 461{ 462 UINT32 i; 463 464 465 ACPI_FUNCTION_TRACE (TbTerminate); 466 467 468 (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); 469 470 /* Delete the individual tables */ 471 472 for (i = 0; i < AcpiGbl_RootTableList.CurrentTableCount; i++) 473 { 474 AcpiTbDeleteTable (&AcpiGbl_RootTableList.Tables[i]); 475 } 476 477 /* 478 * Delete the root table array if allocated locally. Array cannot be 479 * mapped, so we don't need to check for that flag. 480 */ 481 if (AcpiGbl_RootTableList.Flags & ACPI_ROOT_ORIGIN_ALLOCATED) 482 { 483 ACPI_FREE (AcpiGbl_RootTableList.Tables); 484 } 485 486 AcpiGbl_RootTableList.Tables = NULL; 487 AcpiGbl_RootTableList.Flags = 0; 488 AcpiGbl_RootTableList.CurrentTableCount = 0; 489 490 ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "ACPI Tables freed\n")); 491 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 492} 493 494 495/******************************************************************************* 496 * 497 * FUNCTION: AcpiTbDeleteNamespaceByOwner 498 * 499 * PARAMETERS: TableIndex - Table index 500 * 501 * RETURN: Status 502 * 503 * DESCRIPTION: Delete all namespace objects created when this table was loaded. 504 * 505 ******************************************************************************/ 506 507ACPI_STATUS 508AcpiTbDeleteNamespaceByOwner ( 509 UINT32 TableIndex) 510{ 511 ACPI_OWNER_ID OwnerId; 512 ACPI_STATUS Status; 513 514 515 ACPI_FUNCTION_TRACE (TbDeleteNamespaceByOwner); 516 517 518 Status = AcpiUtAcquireMutex (ACPI_MTX_TABLES); 519 if (ACPI_FAILURE (Status)) 520 { 521 return_ACPI_STATUS (Status); 522 } 523 524 if (TableIndex >= AcpiGbl_RootTableList.CurrentTableCount) 525 { 526 /* The table index does not exist */ 527 528 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 529 return_ACPI_STATUS (AE_NOT_EXIST); 530 } 531 532 /* Get the owner ID for this table, used to delete namespace nodes */ 533 534 OwnerId = AcpiGbl_RootTableList.Tables[TableIndex].OwnerId; 535 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 536 537 /* 538 * Need to acquire the namespace writer lock to prevent interference 539 * with any concurrent namespace walks. The interpreter must be 540 * released during the deletion since the acquisition of the deletion 541 * lock may block, and also since the execution of a namespace walk 542 * must be allowed to use the interpreter. 543 */ 544 (void) AcpiUtReleaseMutex (ACPI_MTX_INTERPRETER); 545 Status = AcpiUtAcquireWriteLock (&AcpiGbl_NamespaceRwLock); 546 547 AcpiNsDeleteNamespaceByOwner (OwnerId); 548 if (ACPI_FAILURE (Status)) 549 { 550 return_ACPI_STATUS (Status); 551 } 552 553 AcpiUtReleaseWriteLock (&AcpiGbl_NamespaceRwLock); 554 555 Status = AcpiUtAcquireMutex (ACPI_MTX_INTERPRETER); 556 return_ACPI_STATUS (Status); 557} 558 559 560/******************************************************************************* 561 * 562 * FUNCTION: AcpiTbAllocateOwnerId 563 * 564 * PARAMETERS: TableIndex - Table index 565 * 566 * RETURN: Status 567 * 568 * DESCRIPTION: Allocates OwnerId in TableDesc 569 * 570 ******************************************************************************/ 571 572ACPI_STATUS 573AcpiTbAllocateOwnerId ( 574 UINT32 TableIndex) 575{ 576 ACPI_STATUS Status = AE_BAD_PARAMETER; 577 578 579 ACPI_FUNCTION_TRACE (TbAllocateOwnerId); 580 581 582 (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); 583 if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount) 584 { 585 Status = AcpiUtAllocateOwnerId 586 (&(AcpiGbl_RootTableList.Tables[TableIndex].OwnerId)); 587 } 588 589 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 590 return_ACPI_STATUS (Status); 591} 592 593 594/******************************************************************************* 595 * 596 * FUNCTION: AcpiTbReleaseOwnerId 597 * 598 * PARAMETERS: TableIndex - Table index 599 * 600 * RETURN: Status 601 * 602 * DESCRIPTION: Releases OwnerId in TableDesc 603 * 604 ******************************************************************************/ 605 606ACPI_STATUS 607AcpiTbReleaseOwnerId ( 608 UINT32 TableIndex) 609{ 610 ACPI_STATUS Status = AE_BAD_PARAMETER; 611 612 613 ACPI_FUNCTION_TRACE (TbReleaseOwnerId); 614 615 616 (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); 617 if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount) 618 { 619 AcpiUtReleaseOwnerId ( 620 &(AcpiGbl_RootTableList.Tables[TableIndex].OwnerId)); 621 Status = AE_OK; 622 } 623 624 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 625 return_ACPI_STATUS (Status); 626} 627 628 629/******************************************************************************* 630 * 631 * FUNCTION: AcpiTbGetOwnerId 632 * 633 * PARAMETERS: TableIndex - Table index 634 * OwnerId - Where the table OwnerId is returned 635 * 636 * RETURN: Status 637 * 638 * DESCRIPTION: returns OwnerId for the ACPI table 639 * 640 ******************************************************************************/ 641 642ACPI_STATUS 643AcpiTbGetOwnerId ( 644 UINT32 TableIndex, 645 ACPI_OWNER_ID *OwnerId) 646{ 647 ACPI_STATUS Status = AE_BAD_PARAMETER; 648 649 650 ACPI_FUNCTION_TRACE (TbGetOwnerId); 651 652 653 (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); 654 if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount) 655 { 656 *OwnerId = AcpiGbl_RootTableList.Tables[TableIndex].OwnerId; 657 Status = AE_OK; 658 } 659 660 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 661 return_ACPI_STATUS (Status); 662} 663 664 665/******************************************************************************* 666 * 667 * FUNCTION: AcpiTbIsTableLoaded 668 * 669 * PARAMETERS: TableIndex - Table index 670 * 671 * RETURN: Table Loaded Flag 672 * 673 ******************************************************************************/ 674 675BOOLEAN 676AcpiTbIsTableLoaded ( 677 UINT32 TableIndex) 678{ 679 BOOLEAN IsLoaded = FALSE; 680 681 682 (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); 683 if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount) 684 { 685 IsLoaded = (BOOLEAN) 686 (AcpiGbl_RootTableList.Tables[TableIndex].Flags & 687 ACPI_TABLE_IS_LOADED); 688 } 689 690 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 691 return (IsLoaded); 692} 693 694 695/******************************************************************************* 696 * 697 * FUNCTION: AcpiTbSetTableLoadedFlag 698 * 699 * PARAMETERS: TableIndex - Table index 700 * IsLoaded - TRUE if table is loaded, FALSE otherwise 701 * 702 * RETURN: None 703 * 704 * DESCRIPTION: Sets the table loaded flag to either TRUE or FALSE. 705 * 706 ******************************************************************************/ 707 708void 709AcpiTbSetTableLoadedFlag ( 710 UINT32 TableIndex, 711 BOOLEAN IsLoaded) 712{ 713 714 (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); 715 if (TableIndex < AcpiGbl_RootTableList.CurrentTableCount) 716 { 717 if (IsLoaded) 718 { 719 AcpiGbl_RootTableList.Tables[TableIndex].Flags |= 720 ACPI_TABLE_IS_LOADED; 721 } 722 else 723 { 724 AcpiGbl_RootTableList.Tables[TableIndex].Flags &= 725 ~ACPI_TABLE_IS_LOADED; 726 } 727 } 728 729 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 730} 731
|