1 /****************************************************************************** 2 * 3 * Module Name: tbinstal - ACPI table installation and removal 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2014, 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 __TBINSTAL_C__ 45 46 #include <contrib/dev/acpica/include/acpi.h> 47 #include <contrib/dev/acpica/include/accommon.h> 48 #include <contrib/dev/acpica/include/actables.h> 49 50 #define _COMPONENT ACPI_TABLES 51 ACPI_MODULE_NAME ("tbinstal") 52 53 /* Local prototypes */ 54 55 static BOOLEAN 56 AcpiTbCompareTables ( 57 ACPI_TABLE_DESC *TableDesc, 58 UINT32 TableIndex); 59 60 61 /******************************************************************************* 62 * 63 * FUNCTION: AcpiTbCompareTables 64 * 65 * PARAMETERS: TableDesc - Table 1 descriptor to be compared 66 * TableIndex - Index of table 2 to be compared 67 * 68 * RETURN: TRUE if both tables are identical. 69 * 70 * DESCRIPTION: This function compares a table with another table that has 71 * already been installed in the root table list. 72 * 73 ******************************************************************************/ 74 75 static BOOLEAN 76 AcpiTbCompareTables ( 77 ACPI_TABLE_DESC *TableDesc, 78 UINT32 TableIndex) 79 { 80 ACPI_STATUS Status = AE_OK; 81 BOOLEAN IsIdentical; 82 ACPI_TABLE_HEADER *Table; 83 UINT32 TableLength; 84 UINT8 TableFlags; 85 86 87 Status = AcpiTbAcquireTable (&AcpiGbl_RootTableList.Tables[TableIndex], 88 &Table, &TableLength, &TableFlags); 89 if (ACPI_FAILURE (Status)) 90 { 91 return (FALSE); 92 } 93 94 /* 95 * Check for a table match on the entire table length, 96 * not just the header. 97 */ 98 IsIdentical = (BOOLEAN)((TableDesc->Length != TableLength || 99 ACPI_MEMCMP (TableDesc->Pointer, Table, TableLength)) ? 100 FALSE : TRUE); 101 102 /* Release the acquired table */ 103 104 AcpiTbReleaseTable (Table, TableLength, TableFlags); 105 return (IsIdentical); 106 } 107 108 109 /******************************************************************************* 110 * 111 * FUNCTION: AcpiTbInstallTableWithOverride 112 * 113 * PARAMETERS: TableIndex - Index into root table array 114 * NewTableDesc - New table descriptor to install 115 * Override - Whether override should be performed 116 * 117 * RETURN: None 118 * 119 * DESCRIPTION: Install an ACPI table into the global data structure. The 120 * table override mechanism is called to allow the host 121 * OS to replace any table before it is installed in the root 122 * table array. 123 * 124 ******************************************************************************/ 125 126 void 127 AcpiTbInstallTableWithOverride ( 128 UINT32 TableIndex, 129 ACPI_TABLE_DESC *NewTableDesc, 130 BOOLEAN Override) 131 { 132 133 if (TableIndex >= AcpiGbl_RootTableList.CurrentTableCount) 134 { 135 return; 136 } 137 138 /* 139 * ACPI Table Override: 140 * 141 * Before we install the table, let the host OS override it with a new 142 * one if desired. Any table within the RSDT/XSDT can be replaced, 143 * including the DSDT which is pointed to by the FADT. 144 */ 145 if (Override) 146 { 147 AcpiTbOverrideTable (NewTableDesc); 148 } 149 150 AcpiTbInitTableDescriptor (&AcpiGbl_RootTableList.Tables[TableIndex], 151 NewTableDesc->Address, NewTableDesc->Flags, NewTableDesc->Pointer); 152 153 AcpiTbPrintTableHeader (NewTableDesc->Address, NewTableDesc->Pointer); 154 155 /* Set the global integer width (based upon revision of the DSDT) */ 156 157 if (TableIndex == ACPI_TABLE_INDEX_DSDT) 158 { 159 AcpiUtSetIntegerWidth (NewTableDesc->Pointer->Revision); 160 } 161 } 162 163 164 /******************************************************************************* 165 * 166 * FUNCTION: AcpiTbInstallFixedTable 167 * 168 * PARAMETERS: Address - Physical address of DSDT or FACS 169 * Signature - Table signature, NULL if no need to 170 * match 171 * TableIndex - Index into root table array 172 * 173 * RETURN: Status 174 * 175 * DESCRIPTION: Install a fixed ACPI table (DSDT/FACS) into the global data 176 * structure. 177 * 178 ******************************************************************************/ 179 180 ACPI_STATUS 181 AcpiTbInstallFixedTable ( 182 ACPI_PHYSICAL_ADDRESS Address, 183 char *Signature, 184 UINT32 TableIndex) 185 { 186 ACPI_TABLE_DESC NewTableDesc; 187 ACPI_STATUS Status; 188 189 190 ACPI_FUNCTION_TRACE (TbInstallFixedTable); 191 192 193 if (!Address) 194 { 195 ACPI_ERROR ((AE_INFO, "Null physical address for ACPI table [%s]", 196 Signature)); 197 return (AE_NO_MEMORY); 198 } 199 200 /* Fill a table descriptor for validation */ 201 202 Status = AcpiTbAcquireTempTable (&NewTableDesc, Address, 203 ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL); 204 if (ACPI_FAILURE (Status)) 205 { 206 ACPI_ERROR ((AE_INFO, "Could not acquire table length at %p", 207 ACPI_CAST_PTR (void, Address))); 208 return_ACPI_STATUS (Status); 209 } 210 211 /* Validate and verify a table before installation */ 212 213 Status = AcpiTbVerifyTempTable (&NewTableDesc, Signature); 214 if (ACPI_FAILURE (Status)) 215 { 216 goto ReleaseAndExit; 217 } 218 219 AcpiTbInstallTableWithOverride (TableIndex, &NewTableDesc, TRUE); 220 221 ReleaseAndExit: 222 223 /* Release the temporary table descriptor */ 224 225 AcpiTbReleaseTempTable (&NewTableDesc); 226 return_ACPI_STATUS (Status); 227 } 228 229 230 /******************************************************************************* 231 * 232 * FUNCTION: AcpiTbInstallStandardTable 233 * 234 * PARAMETERS: Address - Address of the table (might be a virtual 235 * address depending on the TableFlags) 236 * Flags - Flags for the table 237 * Reload - Whether reload should be performed 238 * Override - Whether override should be performed 239 * TableIndex - Where the table index is returned 240 * 241 * RETURN: Status 242 * 243 * DESCRIPTION: This function is called to install an ACPI table that is 244 * neither DSDT nor FACS (a "standard" table.) 245 * When this function is called by "Load" or "LoadTable" opcodes, 246 * or by AcpiLoadTable() API, the "Reload" parameter is set. 247 * After sucessfully returning from this function, table is 248 * "INSTALLED" but not "VALIDATED". 249 * 250 ******************************************************************************/ 251 252 ACPI_STATUS 253 AcpiTbInstallStandardTable ( 254 ACPI_PHYSICAL_ADDRESS Address, 255 UINT8 Flags, 256 BOOLEAN Reload, 257 BOOLEAN Override, 258 UINT32 *TableIndex) 259 { 260 UINT32 i; 261 ACPI_STATUS Status = AE_OK; 262 ACPI_TABLE_DESC NewTableDesc; 263 264 265 ACPI_FUNCTION_TRACE (TbInstallStandardTable); 266 267 268 /* Acquire a temporary table descriptor for validation */ 269 270 Status = AcpiTbAcquireTempTable (&NewTableDesc, Address, Flags); 271 if (ACPI_FAILURE (Status)) 272 { 273 ACPI_ERROR ((AE_INFO, "Could not acquire table length at %p", 274 ACPI_CAST_PTR (void, Address))); 275 return_ACPI_STATUS (Status); 276 } 277 278 /* 279 * Optionally do not load any SSDTs from the RSDT/XSDT. This can 280 * be useful for debugging ACPI problems on some machines. 281 */ 282 if (!Reload && 283 AcpiGbl_DisableSsdtTableInstall && 284 ACPI_COMPARE_NAME (&NewTableDesc.Signature, ACPI_SIG_SSDT)) 285 { 286 ACPI_INFO ((AE_INFO, "Ignoring installation of %4.4s at %p", 287 NewTableDesc.Signature.Ascii, ACPI_CAST_PTR (void, Address))); 288 goto ReleaseAndExit; 289 } 290 291 /* Validate and verify a table before installation */ 292 293 Status = AcpiTbVerifyTempTable (&NewTableDesc, NULL); 294 if (ACPI_FAILURE (Status)) 295 { 296 goto ReleaseAndExit; 297 } 298 299 if (Reload) 300 { 301 /* 302 * Validate the incoming table signature. 303 * 304 * 1) Originally, we checked the table signature for "SSDT" or "PSDT". 305 * 2) We added support for OEMx tables, signature "OEM". 306 * 3) Valid tables were encountered with a null signature, so we just 307 * gave up on validating the signature, (05/2008). 308 * 4) We encountered non-AML tables such as the MADT, which caused 309 * interpreter errors and kernel faults. So now, we once again allow 310 * only "SSDT", "OEMx", and now, also a null signature. (05/2011). 311 */ 312 if ((NewTableDesc.Signature.Ascii[0] != 0x00) && 313 (!ACPI_COMPARE_NAME (&NewTableDesc.Signature, ACPI_SIG_SSDT)) && 314 (ACPI_STRNCMP (NewTableDesc.Signature.Ascii, "OEM", 3))) 315 { 316 ACPI_BIOS_ERROR ((AE_INFO, 317 "Table has invalid signature [%4.4s] (0x%8.8X), " 318 "must be SSDT or OEMx", 319 AcpiUtValidAcpiName (NewTableDesc.Signature.Ascii) ? 320 NewTableDesc.Signature.Ascii : "????", 321 NewTableDesc.Signature.Integer)); 322 323 Status = AE_BAD_SIGNATURE; 324 goto ReleaseAndExit; 325 } 326 327 /* Check if table is already registered */ 328 329 for (i = 0; i < AcpiGbl_RootTableList.CurrentTableCount; ++i) 330 { 331 /* 332 * Check for a table match on the entire table length, 333 * not just the header. 334 */ 335 if (!AcpiTbCompareTables (&NewTableDesc, i)) 336 { 337 continue; 338 } 339 340 /* 341 * Note: the current mechanism does not unregister a table if it is 342 * dynamically unloaded. The related namespace entries are deleted, 343 * but the table remains in the root table list. 344 * 345 * The assumption here is that the number of different tables that 346 * will be loaded is actually small, and there is minimal overhead 347 * in just keeping the table in case it is needed again. 348 * 349 * If this assumption changes in the future (perhaps on large 350 * machines with many table load/unload operations), tables will 351 * need to be unregistered when they are unloaded, and slots in the 352 * root table list should be reused when empty. 353 */ 354 if (AcpiGbl_RootTableList.Tables[i].Flags & ACPI_TABLE_IS_LOADED) 355 { 356 /* Table is still loaded, this is an error */ 357 358 Status = AE_ALREADY_EXISTS; 359 goto ReleaseAndExit; 360 } 361 else 362 { 363 /* 364 * Table was unloaded, allow it to be reloaded. 365 * As we are going to return AE_OK to the caller, we should 366 * take the responsibility of freeing the input descriptor. 367 * Refill the input descriptor to ensure 368 * AcpiTbInstallTableWithOverride() can be called again to 369 * indicate the re-installation. 370 */ 371 AcpiTbUninstallTable (&NewTableDesc); 372 *TableIndex = i; 373 (void) AcpiUtReleaseMutex (ACPI_MTX_TABLES); 374 return_ACPI_STATUS (AE_OK); 375 } 376 } 377 } 378 379 /* Add the table to the global root table list */ 380 381 Status = AcpiTbGetNextRootIndex (&i); 382 if (ACPI_FAILURE (Status)) 383 { 384 goto ReleaseAndExit; 385 } 386 387 *TableIndex = i; 388 AcpiTbInstallTableWithOverride (i, &NewTableDesc, Override); 389 390 ReleaseAndExit: 391 392 /* Release the temporary table descriptor */ 393 394 AcpiTbReleaseTempTable (&NewTableDesc); 395 return_ACPI_STATUS (Status); 396 } 397 398 399 /******************************************************************************* 400 * 401 * FUNCTION: AcpiTbOverrideTable 402 * 403 * PARAMETERS: OldTableDesc - Validated table descriptor to be 404 * overridden 405 * 406 * RETURN: None 407 * 408 * DESCRIPTION: Attempt table override by calling the OSL override functions. 409 * Note: If the table is overridden, then the entire new table 410 * is acquired and returned by this function. 411 * Before/after invocation, the table descriptor is in a state 412 * that is "VALIDATED". 413 * 414 ******************************************************************************/ 415 416 void 417 AcpiTbOverrideTable ( 418 ACPI_TABLE_DESC *OldTableDesc) 419 { 420 ACPI_STATUS Status; 421 char *OverrideType; 422 ACPI_TABLE_DESC NewTableDesc; 423 ACPI_TABLE_HEADER *Table; 424 ACPI_PHYSICAL_ADDRESS Address; 425 UINT32 Length; 426 427 428 /* (1) Attempt logical override (returns a logical address) */ 429 430 Status = AcpiOsTableOverride (OldTableDesc->Pointer, &Table); 431 if (ACPI_SUCCESS (Status) && Table) 432 { 433 AcpiTbAcquireTempTable (&NewTableDesc, ACPI_PTR_TO_PHYSADDR (Table), 434 ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL); 435 OverrideType = "Logical"; 436 goto FinishOverride; 437 } 438 439 /* (2) Attempt physical override (returns a physical address) */ 440 441 Status = AcpiOsPhysicalTableOverride (OldTableDesc->Pointer, 442 &Address, &Length); 443 if (ACPI_SUCCESS (Status) && Address && Length) 444 { 445 AcpiTbAcquireTempTable (&NewTableDesc, Address, 446 ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL); 447 OverrideType = "Physical"; 448 goto FinishOverride; 449 } 450 451 return; /* There was no override */ 452 453 454 FinishOverride: 455 456 /* Validate and verify a table before overriding */ 457 458 Status = AcpiTbVerifyTempTable (&NewTableDesc, NULL); 459 if (ACPI_FAILURE (Status)) 460 { 461 return; 462 } 463 464 ACPI_INFO ((AE_INFO, "%4.4s " ACPI_PRINTF_UINT 465 " %s table override, new table: " ACPI_PRINTF_UINT, 466 OldTableDesc->Signature.Ascii, 467 ACPI_FORMAT_TO_UINT (OldTableDesc->Address), 468 OverrideType, ACPI_FORMAT_TO_UINT (NewTableDesc.Address))); 469 470 /* We can now uninstall the original table */ 471 472 AcpiTbUninstallTable (OldTableDesc); 473 474 /* 475 * Replace the original table descriptor and keep its state as 476 * "VALIDATED". 477 */ 478 AcpiTbInitTableDescriptor (OldTableDesc, NewTableDesc.Address, 479 NewTableDesc.Flags, NewTableDesc.Pointer); 480 AcpiTbValidateTempTable (OldTableDesc); 481 482 /* Release the temporary table descriptor */ 483 484 AcpiTbReleaseTempTable (&NewTableDesc); 485 } 486 487 488 /******************************************************************************* 489 * 490 * FUNCTION: AcpiTbStoreTable 491 * 492 * PARAMETERS: Address - Table address 493 * Table - Table header 494 * Length - Table length 495 * Flags - Install flags 496 * TableIndex - Where the table index is returned 497 * 498 * RETURN: Status and table index. 499 * 500 * DESCRIPTION: Add an ACPI table to the global table list 501 * 502 ******************************************************************************/ 503 504 ACPI_STATUS 505 AcpiTbStoreTable ( 506 ACPI_PHYSICAL_ADDRESS Address, 507 ACPI_TABLE_HEADER *Table, 508 UINT32 Length, 509 UINT8 Flags, 510 UINT32 *TableIndex) 511 { 512 ACPI_STATUS Status; 513 ACPI_TABLE_DESC *TableDesc; 514 515 516 Status = AcpiTbGetNextRootIndex (TableIndex); 517 if (ACPI_FAILURE (Status)) 518 { 519 return (Status); 520 } 521 522 /* Initialize added table */ 523 524 TableDesc = &AcpiGbl_RootTableList.Tables[*TableIndex]; 525 AcpiTbInitTableDescriptor (TableDesc, Address, Flags, Table); 526 TableDesc->Pointer = Table; 527 return (AE_OK); 528 } 529 530 531 /******************************************************************************* 532 * 533 * FUNCTION: AcpiTbUninstallTable 534 * 535 * PARAMETERS: TableDesc - Table descriptor 536 * 537 * RETURN: None 538 * 539 * DESCRIPTION: Delete one internal ACPI table 540 * 541 ******************************************************************************/ 542 543 void 544 AcpiTbUninstallTable ( 545 ACPI_TABLE_DESC *TableDesc) 546 { 547 548 ACPI_FUNCTION_TRACE (TbUninstallTable); 549 550 551 /* Table must be installed */ 552 553 if (!TableDesc->Address) 554 { 555 return_VOID; 556 } 557 558 AcpiTbInvalidateTable (TableDesc); 559 560 if ((TableDesc->Flags & ACPI_TABLE_ORIGIN_MASK) == 561 ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL) 562 { 563 ACPI_FREE (ACPI_CAST_PTR (void, TableDesc->Address)); 564 } 565 566 TableDesc->Address = ACPI_PTR_TO_PHYSADDR (NULL); 567 return_VOID; 568 } 569