1 /****************************************************************************** 2 * 3 * Module Name: tbxfload - Table load/unload external interfaces 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2018, 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 ACPI_INIT_FUNCTION 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 Status = AcpiEvInstallRegionHandlers (); 91 if (ACPI_FAILURE (Status)) 92 { 93 ACPI_EXCEPTION ((AE_INFO, Status, "During Region initialization")); 94 return_ACPI_STATUS (Status); 95 } 96 97 /* Load the namespace from the tables */ 98 99 Status = AcpiTbLoadNamespace (); 100 101 /* Don't let single failures abort the load */ 102 103 if (Status == AE_CTRL_TERMINATE) 104 { 105 Status = AE_OK; 106 } 107 108 if (ACPI_FAILURE (Status)) 109 { 110 ACPI_EXCEPTION ((AE_INFO, Status, 111 "While loading namespace from ACPI tables")); 112 } 113 114 if (AcpiGbl_ExecuteTablesAsMethods || !AcpiGbl_GroupModuleLevelCode) 115 { 116 /* 117 * If the module-level code support is enabled, initialize the objects 118 * in the namespace that remain uninitialized. This runs the executable 119 * AML that may be part of the declaration of these name objects: 120 * OperationRegions, BufferFields, Buffers, and Packages. 121 * 122 * Note: The module-level code is optional at this time, but will 123 * become the default in the future. 124 */ 125 Status = AcpiNsInitializeObjects (); 126 if (ACPI_FAILURE (Status)) 127 { 128 return_ACPI_STATUS (Status); 129 } 130 } 131 132 AcpiGbl_NamespaceInitialized = TRUE; 133 return_ACPI_STATUS (Status); 134 } 135 136 ACPI_EXPORT_SYMBOL_INIT (AcpiLoadTables) 137 138 139 /******************************************************************************* 140 * 141 * FUNCTION: AcpiTbLoadNamespace 142 * 143 * PARAMETERS: None 144 * 145 * RETURN: Status 146 * 147 * DESCRIPTION: Load the namespace from the DSDT and all SSDTs/PSDTs found in 148 * the RSDT/XSDT. 149 * 150 ******************************************************************************/ 151 152 ACPI_STATUS 153 AcpiTbLoadNamespace ( 154 void) 155 { 156 ACPI_STATUS Status; 157 UINT32 i; 158 ACPI_TABLE_HEADER *NewDsdt; 159 ACPI_TABLE_DESC *Table; 160 UINT32 TablesLoaded = 0; 161 UINT32 TablesFailed = 0; 162 163 164 ACPI_FUNCTION_TRACE (TbLoadNamespace); 165 166 167 (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); 168 169 #ifdef __ia64__ 170 /* 171 * For ia64 ski emulator 172 */ 173 if (AcpiGbl_DsdtIndex == ACPI_INVALID_TABLE_INDEX) 174 { 175 Status = AE_NO_ACPI_TABLES; 176 goto UnlockAndExit; 177 } 178 #endif 179 180 /* 181 * Load the namespace. The DSDT is required, but any SSDT and 182 * PSDT tables are optional. Verify the DSDT. 183 */ 184 Table = &AcpiGbl_RootTableList.Tables[AcpiGbl_DsdtIndex]; 185 186 if (!AcpiGbl_RootTableList.CurrentTableCount || 187 !ACPI_COMPARE_NAME (Table->Signature.Ascii, ACPI_SIG_DSDT) || 188 ACPI_FAILURE (AcpiTbValidateTable (Table))) 189 { 190 Status = AE_NO_ACPI_TABLES; 191 goto UnlockAndExit; 192 } 193 194 /* 195 * Save the DSDT pointer for simple access. This is the mapped memory 196 * address. We must take care here because the address of the .Tables 197 * array can change dynamically as tables are loaded at run-time. Note: 198 * .Pointer field is not validated until after call to AcpiTbValidateTable. 199 */ 200 AcpiGbl_DSDT = Table->Pointer; 201 202 /* 203 * Optionally copy the entire DSDT to local memory (instead of simply 204 * mapping it.) There are some BIOSs that corrupt or replace the original 205 * DSDT, creating the need for this option. Default is FALSE, do not copy 206 * the DSDT. 207 */ 208 if (AcpiGbl_CopyDsdtLocally) 209 { 210 NewDsdt = AcpiTbCopyDsdt (AcpiGbl_DsdtIndex); 211 if (NewDsdt) 212 { 213 AcpiGbl_DSDT = NewDsdt; 214 } 215 } 216 217 /* 218 * Save the original DSDT header for detection of table corruption 219 * and/or replacement of the DSDT from outside the OS. 220 */ 221 memcpy (&AcpiGbl_OriginalDsdtHeader, AcpiGbl_DSDT, 222 sizeof (ACPI_TABLE_HEADER)); 223 224 /* Load and parse tables */ 225 226 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 227 Status = AcpiNsLoadTable (AcpiGbl_DsdtIndex, AcpiGbl_RootNode); 228 (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); 229 if (ACPI_FAILURE (Status)) 230 { 231 ACPI_EXCEPTION ((AE_INFO, Status, "[DSDT] table load failed")); 232 TablesFailed++; 233 } 234 else 235 { 236 TablesLoaded++; 237 } 238 239 /* Load any SSDT or PSDT tables. Note: Loop leaves tables locked */ 240 241 for (i = 0; i < AcpiGbl_RootTableList.CurrentTableCount; ++i) 242 { 243 Table = &AcpiGbl_RootTableList.Tables[i]; 244 245 if (!Table->Address || 246 (!ACPI_COMPARE_NAME (Table->Signature.Ascii, ACPI_SIG_SSDT) && 247 !ACPI_COMPARE_NAME (Table->Signature.Ascii, ACPI_SIG_PSDT) && 248 !ACPI_COMPARE_NAME (Table->Signature.Ascii, ACPI_SIG_OSDT)) || 249 ACPI_FAILURE (AcpiTbValidateTable (Table))) 250 { 251 continue; 252 } 253 254 /* Ignore errors while loading tables, get as many as possible */ 255 256 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 257 Status = AcpiNsLoadTable (i, AcpiGbl_RootNode); 258 (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); 259 if (ACPI_FAILURE (Status)) 260 { 261 ACPI_EXCEPTION ((AE_INFO, Status, "(%4.4s:%8.8s) while loading table", 262 Table->Signature.Ascii, Table->Pointer->OemTableId)); 263 264 TablesFailed++; 265 266 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT, 267 "Table [%4.4s:%8.8s] (id FF) - Table namespace load failed\n\n", 268 Table->Signature.Ascii, Table->Pointer->OemTableId)); 269 } 270 else 271 { 272 TablesLoaded++; 273 } 274 } 275 276 if (!TablesFailed) 277 { 278 ACPI_INFO (( 279 "%u ACPI AML tables successfully acquired and loaded", 280 TablesLoaded)); 281 } 282 else 283 { 284 ACPI_ERROR ((AE_INFO, 285 "%u table load failures, %u successful", 286 TablesFailed, TablesLoaded)); 287 288 /* Indicate at least one failure */ 289 290 Status = AE_CTRL_TERMINATE; 291 } 292 293 #ifdef ACPI_APPLICATION 294 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT, "\n")); 295 #endif 296 297 298 UnlockAndExit: 299 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 300 return_ACPI_STATUS (Status); 301 } 302 303 304 /******************************************************************************* 305 * 306 * FUNCTION: AcpiInstallTable 307 * 308 * PARAMETERS: Address - Address of the ACPI table to be installed. 309 * Physical - Whether the address is a physical table 310 * address or not 311 * 312 * RETURN: Status 313 * 314 * DESCRIPTION: Dynamically install an ACPI table. 315 * Note: This function should only be invoked after 316 * AcpiInitializeTables() and before AcpiLoadTables(). 317 * 318 ******************************************************************************/ 319 320 ACPI_STATUS ACPI_INIT_FUNCTION 321 AcpiInstallTable ( 322 ACPI_PHYSICAL_ADDRESS Address, 323 BOOLEAN Physical) 324 { 325 ACPI_STATUS Status; 326 UINT8 Flags; 327 UINT32 TableIndex; 328 329 330 ACPI_FUNCTION_TRACE (AcpiInstallTable); 331 332 333 if (Physical) 334 { 335 Flags = ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL; 336 } 337 else 338 { 339 Flags = ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL; 340 } 341 342 Status = AcpiTbInstallStandardTable (Address, Flags, 343 FALSE, FALSE, &TableIndex); 344 345 return_ACPI_STATUS (Status); 346 } 347 348 ACPI_EXPORT_SYMBOL_INIT (AcpiInstallTable) 349 350 351 /******************************************************************************* 352 * 353 * FUNCTION: AcpiLoadTable 354 * 355 * PARAMETERS: Table - Pointer to a buffer containing the ACPI 356 * table to be loaded. 357 * 358 * RETURN: Status 359 * 360 * DESCRIPTION: Dynamically load an ACPI table from the caller's buffer. Must 361 * be a valid ACPI table with a valid ACPI table header. 362 * Note1: Mainly intended to support hotplug addition of SSDTs. 363 * Note2: Does not copy the incoming table. User is responsible 364 * to ensure that the table is not deleted or unmapped. 365 * 366 ******************************************************************************/ 367 368 ACPI_STATUS 369 AcpiLoadTable ( 370 ACPI_TABLE_HEADER *Table) 371 { 372 ACPI_STATUS Status; 373 UINT32 TableIndex; 374 375 376 ACPI_FUNCTION_TRACE (AcpiLoadTable); 377 378 379 /* Parameter validation */ 380 381 if (!Table) 382 { 383 return_ACPI_STATUS (AE_BAD_PARAMETER); 384 } 385 386 /* Install the table and load it into the namespace */ 387 388 ACPI_INFO (("Host-directed Dynamic ACPI Table Load:")); 389 Status = AcpiTbInstallAndLoadTable (ACPI_PTR_TO_PHYSADDR (Table), 390 ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL, FALSE, &TableIndex); 391 return_ACPI_STATUS (Status); 392 } 393 394 ACPI_EXPORT_SYMBOL (AcpiLoadTable) 395 396 397 /******************************************************************************* 398 * 399 * FUNCTION: AcpiUnloadParentTable 400 * 401 * PARAMETERS: Object - Handle to any namespace object owned by 402 * the table to be unloaded 403 * 404 * RETURN: Status 405 * 406 * DESCRIPTION: Via any namespace object within an SSDT or OEMx table, unloads 407 * the table and deletes all namespace objects associated with 408 * that table. Unloading of the DSDT is not allowed. 409 * Note: Mainly intended to support hotplug removal of SSDTs. 410 * 411 ******************************************************************************/ 412 413 ACPI_STATUS 414 AcpiUnloadParentTable ( 415 ACPI_HANDLE Object) 416 { 417 ACPI_NAMESPACE_NODE *Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, Object); 418 ACPI_STATUS Status = AE_NOT_EXIST; 419 ACPI_OWNER_ID OwnerId; 420 UINT32 i; 421 422 423 ACPI_FUNCTION_TRACE (AcpiUnloadParentTable); 424 425 426 /* Parameter validation */ 427 428 if (!Object) 429 { 430 return_ACPI_STATUS (AE_BAD_PARAMETER); 431 } 432 433 /* 434 * The node OwnerId is currently the same as the parent table ID. 435 * However, this could change in the future. 436 */ 437 OwnerId = Node->OwnerId; 438 if (!OwnerId) 439 { 440 /* OwnerId==0 means DSDT is the owner. DSDT cannot be unloaded */ 441 442 return_ACPI_STATUS (AE_TYPE); 443 } 444 445 /* Must acquire the table lock during this operation */ 446 447 Status = AcpiUtAcquireMutex (ACPI_MTX_TABLES); 448 if (ACPI_FAILURE (Status)) 449 { 450 return_ACPI_STATUS (Status); 451 } 452 453 /* Find the table in the global table list */ 454 455 for (i = 0; i < AcpiGbl_RootTableList.CurrentTableCount; i++) 456 { 457 if (OwnerId != AcpiGbl_RootTableList.Tables[i].OwnerId) 458 { 459 continue; 460 } 461 462 /* 463 * Allow unload of SSDT and OEMx tables only. Do not allow unload 464 * of the DSDT. No other types of tables should get here, since 465 * only these types can contain AML and thus are the only types 466 * that can create namespace objects. 467 */ 468 if (ACPI_COMPARE_NAME ( 469 AcpiGbl_RootTableList.Tables[i].Signature.Ascii, 470 ACPI_SIG_DSDT)) 471 { 472 Status = AE_TYPE; 473 break; 474 } 475 476 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 477 Status = AcpiTbUnloadTable (i); 478 (void) AcpiUtAcquireMutex (ACPI_MTX_TABLES); 479 break; 480 } 481 482 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 483 return_ACPI_STATUS (Status); 484 } 485 486 ACPI_EXPORT_SYMBOL (AcpiUnloadParentTable) 487