1 /****************************************************************************** 2 * 3 * Module Name: tbxfload - Table load/unload external interfaces 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2016, 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 #define EXPORT_ACPI_INTERFACES 45 46 #include "acpi.h" 47 #include "accommon.h" 48 #include "acnamesp.h" 49 #include "actables.h" 50 #include "acevents.h" 51 52 #define _COMPONENT ACPI_TABLES 53 ACPI_MODULE_NAME ("tbxfload") 54 55 56 /******************************************************************************* 57 * 58 * FUNCTION: AcpiLoadTables 59 * 60 * PARAMETERS: None 61 * 62 * RETURN: Status 63 * 64 * DESCRIPTION: Load the ACPI tables from the RSDT/XSDT 65 * 66 ******************************************************************************/ 67 68 ACPI_STATUS 69 AcpiLoadTables ( 70 void) 71 { 72 ACPI_STATUS Status; 73 74 75 ACPI_FUNCTION_TRACE (AcpiLoadTables); 76 77 78 /* 79 * Install the default operation region handlers. These are the 80 * handlers that are defined by the ACPI specification to be 81 * "always accessible" -- namely, SystemMemory, SystemIO, and 82 * PCI_Config. This also means that no _REG methods need to be 83 * run for these address spaces. We need to have these handlers 84 * installed before any AML code can be executed, especially any 85 * module-level code (11/2015). 86 * Note that we allow OSPMs to install their own region handlers 87 * between AcpiInitializeSubsystem() and AcpiLoadTables() to use 88 * their customized default region handlers. 89 */ 90 if (AcpiGbl_GroupModuleLevelCode) 91 { 92 Status = AcpiEvInstallRegionHandlers (); 93 if (ACPI_FAILURE (Status) && Status != AE_ALREADY_EXISTS) 94 { 95 ACPI_EXCEPTION ((AE_INFO, Status, "During Region initialization")); 96 return_ACPI_STATUS (Status); 97 } 98 } 99 100 /* Load the namespace from the tables */ 101 102 Status = AcpiTbLoadNamespace (); 103 104 /* Don't let single failures abort the load */ 105 106 if (Status == AE_CTRL_TERMINATE) 107 { 108 Status = AE_OK; 109 } 110 111 if (ACPI_FAILURE (Status)) 112 { 113 ACPI_EXCEPTION ((AE_INFO, Status, 114 "While loading namespace from ACPI tables")); 115 } 116 117 return_ACPI_STATUS (Status); 118 } 119 120 ACPI_EXPORT_SYMBOL_INIT (AcpiLoadTables) 121 122 123 /******************************************************************************* 124 * 125 * FUNCTION: AcpiTbLoadNamespace 126 * 127 * PARAMETERS: None 128 * 129 * RETURN: Status 130 * 131 * DESCRIPTION: Load the namespace from the DSDT and all SSDTs/PSDTs found in 132 * the RSDT/XSDT. 133 * 134 ******************************************************************************/ 135 136 ACPI_STATUS 137 AcpiTbLoadNamespace ( 138 void) 139 { 140 ACPI_STATUS Status; 141 UINT32 i; 142 ACPI_TABLE_HEADER *NewDsdt; 143 ACPI_TABLE_DESC *Table; 144 UINT32 TablesLoaded = 0; 145 UINT32 TablesFailed = 0; 146 147 148 ACPI_FUNCTION_TRACE (TbLoadNamespace); 149 150 151 (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); 152 153 /* 154 * Load the namespace. The DSDT is required, but any SSDT and 155 * PSDT tables are optional. Verify the DSDT. 156 */ 157 Table = &AcpiGbl_RootTableList.Tables[AcpiGbl_DsdtIndex]; 158 159 if (!AcpiGbl_RootTableList.CurrentTableCount || 160 !ACPI_COMPARE_NAME (Table->Signature.Ascii, ACPI_SIG_DSDT) || 161 ACPI_FAILURE (AcpiTbValidateTable (Table))) 162 { 163 Status = AE_NO_ACPI_TABLES; 164 goto UnlockAndExit; 165 } 166 167 /* 168 * Save the DSDT pointer for simple access. This is the mapped memory 169 * address. We must take care here because the address of the .Tables 170 * array can change dynamically as tables are loaded at run-time. Note: 171 * .Pointer field is not validated until after call to AcpiTbValidateTable. 172 */ 173 AcpiGbl_DSDT = Table->Pointer; 174 175 /* 176 * Optionally copy the entire DSDT to local memory (instead of simply 177 * mapping it.) There are some BIOSs that corrupt or replace the original 178 * DSDT, creating the need for this option. Default is FALSE, do not copy 179 * the DSDT. 180 */ 181 if (AcpiGbl_CopyDsdtLocally) 182 { 183 NewDsdt = AcpiTbCopyDsdt (AcpiGbl_DsdtIndex); 184 if (NewDsdt) 185 { 186 AcpiGbl_DSDT = NewDsdt; 187 } 188 } 189 190 /* 191 * Save the original DSDT header for detection of table corruption 192 * and/or replacement of the DSDT from outside the OS. 193 */ 194 memcpy (&AcpiGbl_OriginalDsdtHeader, AcpiGbl_DSDT, 195 sizeof (ACPI_TABLE_HEADER)); 196 197 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 198 199 /* Load and parse tables */ 200 201 Status = AcpiNsLoadTable (AcpiGbl_DsdtIndex, AcpiGbl_RootNode); 202 if (ACPI_FAILURE (Status)) 203 { 204 ACPI_EXCEPTION ((AE_INFO, Status, "[DSDT] table load failed")); 205 TablesFailed++; 206 } 207 else 208 { 209 TablesLoaded++; 210 } 211 212 /* Load any SSDT or PSDT tables. Note: Loop leaves tables locked */ 213 214 (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); 215 for (i = 0; i < AcpiGbl_RootTableList.CurrentTableCount; ++i) 216 { 217 Table = &AcpiGbl_RootTableList.Tables[i]; 218 219 if (!AcpiGbl_RootTableList.Tables[i].Address || 220 (!ACPI_COMPARE_NAME (Table->Signature.Ascii, ACPI_SIG_SSDT) && 221 !ACPI_COMPARE_NAME (Table->Signature.Ascii, ACPI_SIG_PSDT) && 222 !ACPI_COMPARE_NAME (Table->Signature.Ascii, ACPI_SIG_OSDT)) || 223 ACPI_FAILURE (AcpiTbValidateTable (Table))) 224 { 225 continue; 226 } 227 228 /* Ignore errors while loading tables, get as many as possible */ 229 230 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 231 Status = AcpiNsLoadTable (i, AcpiGbl_RootNode); 232 if (ACPI_FAILURE (Status)) 233 { 234 ACPI_EXCEPTION ((AE_INFO, Status, "(%4.4s:%8.8s) while loading table", 235 Table->Signature.Ascii, Table->Pointer->OemTableId)); 236 237 TablesFailed++; 238 239 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT, 240 "Table [%4.4s:%8.8s] (id FF) - Table namespace load failed\n\n", 241 Table->Signature.Ascii, Table->Pointer->OemTableId)); 242 } 243 else 244 { 245 TablesLoaded++; 246 } 247 248 (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); 249 } 250 251 if (!TablesFailed) 252 { 253 ACPI_INFO (( 254 "%u ACPI AML tables successfully acquired and loaded", 255 TablesLoaded)); 256 } 257 else 258 { 259 ACPI_ERROR ((AE_INFO, 260 "%u table load failures, %u successful", 261 TablesFailed, TablesLoaded)); 262 263 /* Indicate at least one failure */ 264 265 Status = AE_CTRL_TERMINATE; 266 } 267 268 UnlockAndExit: 269 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 270 return_ACPI_STATUS (Status); 271 } 272 273 274 /******************************************************************************* 275 * 276 * FUNCTION: AcpiInstallTable 277 * 278 * PARAMETERS: Address - Address of the ACPI table to be installed. 279 * Physical - Whether the address is a physical table 280 * address or not 281 * 282 * RETURN: Status 283 * 284 * DESCRIPTION: Dynamically install an ACPI table. 285 * Note: This function should only be invoked after 286 * AcpiInitializeTables() and before AcpiLoadTables(). 287 * 288 ******************************************************************************/ 289 290 ACPI_STATUS 291 AcpiInstallTable ( 292 ACPI_PHYSICAL_ADDRESS Address, 293 BOOLEAN Physical) 294 { 295 ACPI_STATUS Status; 296 UINT8 Flags; 297 UINT32 TableIndex; 298 299 300 ACPI_FUNCTION_TRACE (AcpiInstallTable); 301 302 303 if (Physical) 304 { 305 Flags = ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL; 306 } 307 else 308 { 309 Flags = ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL; 310 } 311 312 Status = AcpiTbInstallStandardTable (Address, Flags, 313 FALSE, FALSE, &TableIndex); 314 315 return_ACPI_STATUS (Status); 316 } 317 318 ACPI_EXPORT_SYMBOL_INIT (AcpiInstallTable) 319 320 321 /******************************************************************************* 322 * 323 * FUNCTION: AcpiLoadTable 324 * 325 * PARAMETERS: Table - Pointer to a buffer containing the ACPI 326 * table to be loaded. 327 * 328 * RETURN: Status 329 * 330 * DESCRIPTION: Dynamically load an ACPI table from the caller's buffer. Must 331 * be a valid ACPI table with a valid ACPI table header. 332 * Note1: Mainly intended to support hotplug addition of SSDTs. 333 * Note2: Does not copy the incoming table. User is responsible 334 * to ensure that the table is not deleted or unmapped. 335 * 336 ******************************************************************************/ 337 338 ACPI_STATUS 339 AcpiLoadTable ( 340 ACPI_TABLE_HEADER *Table) 341 { 342 ACPI_STATUS Status; 343 UINT32 TableIndex; 344 345 346 ACPI_FUNCTION_TRACE (AcpiLoadTable); 347 348 349 /* Parameter validation */ 350 351 if (!Table) 352 { 353 return_ACPI_STATUS (AE_BAD_PARAMETER); 354 } 355 356 /* Must acquire the interpreter lock during this operation */ 357 358 Status = AcpiUtAcquireMutex (ACPI_MTX_INTERPRETER); 359 if (ACPI_FAILURE (Status)) 360 { 361 return_ACPI_STATUS (Status); 362 } 363 364 /* Install the table and load it into the namespace */ 365 366 ACPI_INFO (("Host-directed Dynamic ACPI Table Load:")); 367 (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); 368 369 Status = AcpiTbInstallStandardTable (ACPI_PTR_TO_PHYSADDR (Table), 370 ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL, TRUE, FALSE, 371 &TableIndex); 372 373 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 374 if (ACPI_FAILURE (Status)) 375 { 376 goto UnlockAndExit; 377 } 378 379 /* 380 * Note: Now table is "INSTALLED", it must be validated before 381 * using. 382 */ 383 Status = AcpiTbValidateTable ( 384 &AcpiGbl_RootTableList.Tables[TableIndex]); 385 if (ACPI_FAILURE (Status)) 386 { 387 goto UnlockAndExit; 388 } 389 390 Status = AcpiNsLoadTable (TableIndex, AcpiGbl_RootNode); 391 392 /* Invoke table handler if present */ 393 394 if (AcpiGbl_TableHandler) 395 { 396 (void) AcpiGbl_TableHandler (ACPI_TABLE_EVENT_LOAD, Table, 397 AcpiGbl_TableHandlerContext); 398 } 399 400 UnlockAndExit: 401 (void) AcpiUtReleaseMutex (ACPI_MTX_INTERPRETER); 402 return_ACPI_STATUS (Status); 403 } 404 405 ACPI_EXPORT_SYMBOL (AcpiLoadTable) 406 407 408 /******************************************************************************* 409 * 410 * FUNCTION: AcpiUnloadParentTable 411 * 412 * PARAMETERS: Object - Handle to any namespace object owned by 413 * the table to be unloaded 414 * 415 * RETURN: Status 416 * 417 * DESCRIPTION: Via any namespace object within an SSDT or OEMx table, unloads 418 * the table and deletes all namespace objects associated with 419 * that table. Unloading of the DSDT is not allowed. 420 * Note: Mainly intended to support hotplug removal of SSDTs. 421 * 422 ******************************************************************************/ 423 424 ACPI_STATUS 425 AcpiUnloadParentTable ( 426 ACPI_HANDLE Object) 427 { 428 ACPI_NAMESPACE_NODE *Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, Object); 429 ACPI_STATUS Status = AE_NOT_EXIST; 430 ACPI_OWNER_ID OwnerId; 431 UINT32 i; 432 433 434 ACPI_FUNCTION_TRACE (AcpiUnloadParentTable); 435 436 437 /* Parameter validation */ 438 439 if (!Object) 440 { 441 return_ACPI_STATUS (AE_BAD_PARAMETER); 442 } 443 444 /* 445 * The node OwnerId is currently the same as the parent table ID. 446 * However, this could change in the future. 447 */ 448 OwnerId = Node->OwnerId; 449 if (!OwnerId) 450 { 451 /* OwnerId==0 means DSDT is the owner. DSDT cannot be unloaded */ 452 453 return_ACPI_STATUS (AE_TYPE); 454 } 455 456 /* Must acquire the interpreter lock during this operation */ 457 458 Status = AcpiUtAcquireMutex (ACPI_MTX_INTERPRETER); 459 if (ACPI_FAILURE (Status)) 460 { 461 return_ACPI_STATUS (Status); 462 } 463 464 /* Find the table in the global table list */ 465 466 for (i = 0; i < AcpiGbl_RootTableList.CurrentTableCount; i++) 467 { 468 if (OwnerId != AcpiGbl_RootTableList.Tables[i].OwnerId) 469 { 470 continue; 471 } 472 473 /* 474 * Allow unload of SSDT and OEMx tables only. Do not allow unload 475 * of the DSDT. No other types of tables should get here, since 476 * only these types can contain AML and thus are the only types 477 * that can create namespace objects. 478 */ 479 if (ACPI_COMPARE_NAME ( 480 AcpiGbl_RootTableList.Tables[i].Signature.Ascii, 481 ACPI_SIG_DSDT)) 482 { 483 Status = AE_TYPE; 484 break; 485 } 486 487 /* Ensure the table is actually loaded */ 488 489 if (!AcpiTbIsTableLoaded (i)) 490 { 491 Status = AE_NOT_EXIST; 492 break; 493 } 494 495 /* Invoke table handler if present */ 496 497 if (AcpiGbl_TableHandler) 498 { 499 (void) AcpiGbl_TableHandler (ACPI_TABLE_EVENT_UNLOAD, 500 AcpiGbl_RootTableList.Tables[i].Pointer, 501 AcpiGbl_TableHandlerContext); 502 } 503 504 /* 505 * Delete all namespace objects owned by this table. Note that 506 * these objects can appear anywhere in the namespace by virtue 507 * of the AML "Scope" operator. Thus, we need to track ownership 508 * by an ID, not simply a position within the hierarchy. 509 */ 510 Status = AcpiTbDeleteNamespaceByOwner (i); 511 if (ACPI_FAILURE (Status)) 512 { 513 break; 514 } 515 516 Status = AcpiTbReleaseOwnerId (i); 517 AcpiTbSetTableLoadedFlag (i, FALSE); 518 break; 519 } 520 521 (void) AcpiUtReleaseMutex (ACPI_MTX_INTERPRETER); 522 return_ACPI_STATUS (Status); 523 } 524 525 ACPI_EXPORT_SYMBOL (AcpiUnloadParentTable) 526