1a159c266SJung-uk Kim /****************************************************************************** 2a159c266SJung-uk Kim * 3a159c266SJung-uk Kim * Module Name: tbinstal - ACPI table installation and removal 4a159c266SJung-uk Kim * 5a159c266SJung-uk Kim *****************************************************************************/ 6a159c266SJung-uk Kim 7a159c266SJung-uk Kim /* 81c0e1b6dSJung-uk Kim * Copyright (C) 2000 - 2015, Intel Corp. 9a159c266SJung-uk Kim * All rights reserved. 10a159c266SJung-uk Kim * 11a159c266SJung-uk Kim * Redistribution and use in source and binary forms, with or without 12a159c266SJung-uk Kim * modification, are permitted provided that the following conditions 13a159c266SJung-uk Kim * are met: 14a159c266SJung-uk Kim * 1. Redistributions of source code must retain the above copyright 15a159c266SJung-uk Kim * notice, this list of conditions, and the following disclaimer, 16a159c266SJung-uk Kim * without modification. 17a159c266SJung-uk Kim * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18a159c266SJung-uk Kim * substantially similar to the "NO WARRANTY" disclaimer below 19a159c266SJung-uk Kim * ("Disclaimer") and any redistribution must be conditioned upon 20a159c266SJung-uk Kim * including a substantially similar Disclaimer requirement for further 21a159c266SJung-uk Kim * binary redistribution. 22a159c266SJung-uk Kim * 3. Neither the names of the above-listed copyright holders nor the names 23a159c266SJung-uk Kim * of any contributors may be used to endorse or promote products derived 24a159c266SJung-uk Kim * from this software without specific prior written permission. 25a159c266SJung-uk Kim * 26a159c266SJung-uk Kim * Alternatively, this software may be distributed under the terms of the 27a159c266SJung-uk Kim * GNU General Public License ("GPL") version 2 as published by the Free 28a159c266SJung-uk Kim * Software Foundation. 29a159c266SJung-uk Kim * 30a159c266SJung-uk Kim * NO WARRANTY 31a159c266SJung-uk Kim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32a159c266SJung-uk Kim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33a159c266SJung-uk Kim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34a159c266SJung-uk Kim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35a159c266SJung-uk Kim * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36a159c266SJung-uk Kim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37a159c266SJung-uk Kim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38a159c266SJung-uk Kim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39a159c266SJung-uk Kim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40a159c266SJung-uk Kim * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41a159c266SJung-uk Kim * POSSIBILITY OF SUCH DAMAGES. 42a159c266SJung-uk Kim */ 43a159c266SJung-uk Kim 44a159c266SJung-uk Kim #include <contrib/dev/acpica/include/acpi.h> 45a159c266SJung-uk Kim #include <contrib/dev/acpica/include/accommon.h> 46a159c266SJung-uk Kim #include <contrib/dev/acpica/include/actables.h> 47a159c266SJung-uk Kim 48a159c266SJung-uk Kim #define _COMPONENT ACPI_TABLES 49a159c266SJung-uk Kim ACPI_MODULE_NAME ("tbinstal") 50a159c266SJung-uk Kim 51313a0c13SJung-uk Kim /* Local prototypes */ 52a159c266SJung-uk Kim 53313a0c13SJung-uk Kim static BOOLEAN 54313a0c13SJung-uk Kim AcpiTbCompareTables ( 55313a0c13SJung-uk Kim ACPI_TABLE_DESC *TableDesc, 56313a0c13SJung-uk Kim UINT32 TableIndex); 57313a0c13SJung-uk Kim 58313a0c13SJung-uk Kim 59313a0c13SJung-uk Kim /******************************************************************************* 60a159c266SJung-uk Kim * 61313a0c13SJung-uk Kim * FUNCTION: AcpiTbCompareTables 62a159c266SJung-uk Kim * 63313a0c13SJung-uk Kim * PARAMETERS: TableDesc - Table 1 descriptor to be compared 64313a0c13SJung-uk Kim * TableIndex - Index of table 2 to be compared 65313a0c13SJung-uk Kim * 66313a0c13SJung-uk Kim * RETURN: TRUE if both tables are identical. 67313a0c13SJung-uk Kim * 68313a0c13SJung-uk Kim * DESCRIPTION: This function compares a table with another table that has 69313a0c13SJung-uk Kim * already been installed in the root table list. 70313a0c13SJung-uk Kim * 71313a0c13SJung-uk Kim ******************************************************************************/ 72313a0c13SJung-uk Kim 73313a0c13SJung-uk Kim static BOOLEAN 74313a0c13SJung-uk Kim AcpiTbCompareTables ( 75313a0c13SJung-uk Kim ACPI_TABLE_DESC *TableDesc, 76313a0c13SJung-uk Kim UINT32 TableIndex) 77313a0c13SJung-uk Kim { 78313a0c13SJung-uk Kim ACPI_STATUS Status = AE_OK; 79313a0c13SJung-uk Kim BOOLEAN IsIdentical; 80313a0c13SJung-uk Kim ACPI_TABLE_HEADER *Table; 81313a0c13SJung-uk Kim UINT32 TableLength; 82313a0c13SJung-uk Kim UINT8 TableFlags; 83313a0c13SJung-uk Kim 84313a0c13SJung-uk Kim 85313a0c13SJung-uk Kim Status = AcpiTbAcquireTable (&AcpiGbl_RootTableList.Tables[TableIndex], 86313a0c13SJung-uk Kim &Table, &TableLength, &TableFlags); 87313a0c13SJung-uk Kim if (ACPI_FAILURE (Status)) 88313a0c13SJung-uk Kim { 89313a0c13SJung-uk Kim return (FALSE); 90313a0c13SJung-uk Kim } 91313a0c13SJung-uk Kim 92313a0c13SJung-uk Kim /* 93313a0c13SJung-uk Kim * Check for a table match on the entire table length, 94313a0c13SJung-uk Kim * not just the header. 95313a0c13SJung-uk Kim */ 96313a0c13SJung-uk Kim IsIdentical = (BOOLEAN)((TableDesc->Length != TableLength || 975ef50723SJung-uk Kim memcmp (TableDesc->Pointer, Table, TableLength)) ? 98313a0c13SJung-uk Kim FALSE : TRUE); 99313a0c13SJung-uk Kim 100313a0c13SJung-uk Kim /* Release the acquired table */ 101313a0c13SJung-uk Kim 102313a0c13SJung-uk Kim AcpiTbReleaseTable (Table, TableLength, TableFlags); 103313a0c13SJung-uk Kim return (IsIdentical); 104313a0c13SJung-uk Kim } 105313a0c13SJung-uk Kim 106313a0c13SJung-uk Kim 107313a0c13SJung-uk Kim /******************************************************************************* 108313a0c13SJung-uk Kim * 109313a0c13SJung-uk Kim * FUNCTION: AcpiTbInstallTableWithOverride 110313a0c13SJung-uk Kim * 111*70e6ab8fSJung-uk Kim * PARAMETERS: NewTableDesc - New table descriptor to install 112313a0c13SJung-uk Kim * Override - Whether override should be performed 113*70e6ab8fSJung-uk Kim * TableIndex - Where the table index is returned 114313a0c13SJung-uk Kim * 115313a0c13SJung-uk Kim * RETURN: None 116313a0c13SJung-uk Kim * 117313a0c13SJung-uk Kim * DESCRIPTION: Install an ACPI table into the global data structure. The 118313a0c13SJung-uk Kim * table override mechanism is called to allow the host 119313a0c13SJung-uk Kim * OS to replace any table before it is installed in the root 120313a0c13SJung-uk Kim * table array. 121313a0c13SJung-uk Kim * 122313a0c13SJung-uk Kim ******************************************************************************/ 123313a0c13SJung-uk Kim 124313a0c13SJung-uk Kim void 125313a0c13SJung-uk Kim AcpiTbInstallTableWithOverride ( 126313a0c13SJung-uk Kim ACPI_TABLE_DESC *NewTableDesc, 127*70e6ab8fSJung-uk Kim BOOLEAN Override, 128*70e6ab8fSJung-uk Kim UINT32 *TableIndex) 129313a0c13SJung-uk Kim { 130*70e6ab8fSJung-uk Kim UINT32 i; 131*70e6ab8fSJung-uk Kim ACPI_STATUS Status; 132313a0c13SJung-uk Kim 133*70e6ab8fSJung-uk Kim 134*70e6ab8fSJung-uk Kim Status = AcpiTbGetNextTableDescriptor (&i, NULL); 135*70e6ab8fSJung-uk Kim if (ACPI_FAILURE (Status)) 136313a0c13SJung-uk Kim { 137313a0c13SJung-uk Kim return; 138313a0c13SJung-uk Kim } 139313a0c13SJung-uk Kim 140313a0c13SJung-uk Kim /* 141313a0c13SJung-uk Kim * ACPI Table Override: 142313a0c13SJung-uk Kim * 143313a0c13SJung-uk Kim * Before we install the table, let the host OS override it with a new 144313a0c13SJung-uk Kim * one if desired. Any table within the RSDT/XSDT can be replaced, 145313a0c13SJung-uk Kim * including the DSDT which is pointed to by the FADT. 146313a0c13SJung-uk Kim */ 147313a0c13SJung-uk Kim if (Override) 148313a0c13SJung-uk Kim { 149313a0c13SJung-uk Kim AcpiTbOverrideTable (NewTableDesc); 150313a0c13SJung-uk Kim } 151313a0c13SJung-uk Kim 152*70e6ab8fSJung-uk Kim AcpiTbInitTableDescriptor (&AcpiGbl_RootTableList.Tables[i], 153313a0c13SJung-uk Kim NewTableDesc->Address, NewTableDesc->Flags, NewTableDesc->Pointer); 154313a0c13SJung-uk Kim 155313a0c13SJung-uk Kim AcpiTbPrintTableHeader (NewTableDesc->Address, NewTableDesc->Pointer); 156313a0c13SJung-uk Kim 157*70e6ab8fSJung-uk Kim /* This synchronizes AcpiGbl_DsdtIndex */ 158*70e6ab8fSJung-uk Kim 159*70e6ab8fSJung-uk Kim *TableIndex = i; 160*70e6ab8fSJung-uk Kim 161313a0c13SJung-uk Kim /* Set the global integer width (based upon revision of the DSDT) */ 162313a0c13SJung-uk Kim 163*70e6ab8fSJung-uk Kim if (i == AcpiGbl_DsdtIndex) 164313a0c13SJung-uk Kim { 165313a0c13SJung-uk Kim AcpiUtSetIntegerWidth (NewTableDesc->Pointer->Revision); 166313a0c13SJung-uk Kim } 167313a0c13SJung-uk Kim } 168313a0c13SJung-uk Kim 169313a0c13SJung-uk Kim 170313a0c13SJung-uk Kim /******************************************************************************* 171313a0c13SJung-uk Kim * 172313a0c13SJung-uk Kim * FUNCTION: AcpiTbInstallFixedTable 173313a0c13SJung-uk Kim * 174313a0c13SJung-uk Kim * PARAMETERS: Address - Physical address of DSDT or FACS 175313a0c13SJung-uk Kim * Signature - Table signature, NULL if no need to 176313a0c13SJung-uk Kim * match 177*70e6ab8fSJung-uk Kim * TableIndex - Where the table index is returned 178a159c266SJung-uk Kim * 179a159c266SJung-uk Kim * RETURN: Status 180a159c266SJung-uk Kim * 181313a0c13SJung-uk Kim * DESCRIPTION: Install a fixed ACPI table (DSDT/FACS) into the global data 182313a0c13SJung-uk Kim * structure. 183a159c266SJung-uk Kim * 184313a0c13SJung-uk Kim ******************************************************************************/ 185a159c266SJung-uk Kim 186a159c266SJung-uk Kim ACPI_STATUS 187313a0c13SJung-uk Kim AcpiTbInstallFixedTable ( 188313a0c13SJung-uk Kim ACPI_PHYSICAL_ADDRESS Address, 189313a0c13SJung-uk Kim char *Signature, 190*70e6ab8fSJung-uk Kim UINT32 *TableIndex) 191a159c266SJung-uk Kim { 192313a0c13SJung-uk Kim ACPI_TABLE_DESC NewTableDesc; 193313a0c13SJung-uk Kim ACPI_STATUS Status; 194a159c266SJung-uk Kim 195a159c266SJung-uk Kim 196313a0c13SJung-uk Kim ACPI_FUNCTION_TRACE (TbInstallFixedTable); 197a159c266SJung-uk Kim 198a159c266SJung-uk Kim 199313a0c13SJung-uk Kim if (!Address) 200a159c266SJung-uk Kim { 201313a0c13SJung-uk Kim ACPI_ERROR ((AE_INFO, "Null physical address for ACPI table [%s]", 202313a0c13SJung-uk Kim Signature)); 203313a0c13SJung-uk Kim return (AE_NO_MEMORY); 204a159c266SJung-uk Kim } 205a159c266SJung-uk Kim 206313a0c13SJung-uk Kim /* Fill a table descriptor for validation */ 207313a0c13SJung-uk Kim 208313a0c13SJung-uk Kim Status = AcpiTbAcquireTempTable (&NewTableDesc, Address, 209313a0c13SJung-uk Kim ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL); 210313a0c13SJung-uk Kim if (ACPI_FAILURE (Status)) 211a159c266SJung-uk Kim { 2127cf3e94aSJung-uk Kim ACPI_ERROR ((AE_INFO, "Could not acquire table length at %8.8X%8.8X", 2137cf3e94aSJung-uk Kim ACPI_FORMAT_UINT64 (Address))); 214313a0c13SJung-uk Kim return_ACPI_STATUS (Status); 215a159c266SJung-uk Kim } 216a159c266SJung-uk Kim 217313a0c13SJung-uk Kim /* Validate and verify a table before installation */ 218a159c266SJung-uk Kim 219313a0c13SJung-uk Kim Status = AcpiTbVerifyTempTable (&NewTableDesc, Signature); 220313a0c13SJung-uk Kim if (ACPI_FAILURE (Status)) 221313a0c13SJung-uk Kim { 222313a0c13SJung-uk Kim goto ReleaseAndExit; 223313a0c13SJung-uk Kim } 224a159c266SJung-uk Kim 225*70e6ab8fSJung-uk Kim /* Add the table to the global root table list */ 226*70e6ab8fSJung-uk Kim 227*70e6ab8fSJung-uk Kim AcpiTbInstallTableWithOverride (&NewTableDesc, TRUE, TableIndex); 228313a0c13SJung-uk Kim 229313a0c13SJung-uk Kim ReleaseAndExit: 230313a0c13SJung-uk Kim 231313a0c13SJung-uk Kim /* Release the temporary table descriptor */ 232313a0c13SJung-uk Kim 233313a0c13SJung-uk Kim AcpiTbReleaseTempTable (&NewTableDesc); 234a159c266SJung-uk Kim return_ACPI_STATUS (Status); 235a159c266SJung-uk Kim } 236a159c266SJung-uk Kim 237a159c266SJung-uk Kim 238a159c266SJung-uk Kim /******************************************************************************* 239a159c266SJung-uk Kim * 240313a0c13SJung-uk Kim * FUNCTION: AcpiTbInstallStandardTable 241a159c266SJung-uk Kim * 242313a0c13SJung-uk Kim * PARAMETERS: Address - Address of the table (might be a virtual 243313a0c13SJung-uk Kim * address depending on the TableFlags) 244313a0c13SJung-uk Kim * Flags - Flags for the table 245313a0c13SJung-uk Kim * Reload - Whether reload should be performed 246313a0c13SJung-uk Kim * Override - Whether override should be performed 247a159c266SJung-uk Kim * TableIndex - Where the table index is returned 248a159c266SJung-uk Kim * 249a159c266SJung-uk Kim * RETURN: Status 250a159c266SJung-uk Kim * 251313a0c13SJung-uk Kim * DESCRIPTION: This function is called to install an ACPI table that is 252313a0c13SJung-uk Kim * neither DSDT nor FACS (a "standard" table.) 253313a0c13SJung-uk Kim * When this function is called by "Load" or "LoadTable" opcodes, 254313a0c13SJung-uk Kim * or by AcpiLoadTable() API, the "Reload" parameter is set. 255313a0c13SJung-uk Kim * After sucessfully returning from this function, table is 256313a0c13SJung-uk Kim * "INSTALLED" but not "VALIDATED". 257a159c266SJung-uk Kim * 258a159c266SJung-uk Kim ******************************************************************************/ 259a159c266SJung-uk Kim 260a159c266SJung-uk Kim ACPI_STATUS 261313a0c13SJung-uk Kim AcpiTbInstallStandardTable ( 262313a0c13SJung-uk Kim ACPI_PHYSICAL_ADDRESS Address, 263313a0c13SJung-uk Kim UINT8 Flags, 264313a0c13SJung-uk Kim BOOLEAN Reload, 265313a0c13SJung-uk Kim BOOLEAN Override, 266a159c266SJung-uk Kim UINT32 *TableIndex) 267a159c266SJung-uk Kim { 268a159c266SJung-uk Kim UINT32 i; 269a159c266SJung-uk Kim ACPI_STATUS Status = AE_OK; 270313a0c13SJung-uk Kim ACPI_TABLE_DESC NewTableDesc; 271a159c266SJung-uk Kim 272a159c266SJung-uk Kim 273313a0c13SJung-uk Kim ACPI_FUNCTION_TRACE (TbInstallStandardTable); 274a159c266SJung-uk Kim 275a159c266SJung-uk Kim 276313a0c13SJung-uk Kim /* Acquire a temporary table descriptor for validation */ 277313a0c13SJung-uk Kim 278313a0c13SJung-uk Kim Status = AcpiTbAcquireTempTable (&NewTableDesc, Address, Flags); 279313a0c13SJung-uk Kim if (ACPI_FAILURE (Status)) 280a159c266SJung-uk Kim { 2817cf3e94aSJung-uk Kim ACPI_ERROR ((AE_INFO, "Could not acquire table length at %8.8X%8.8X", 2827cf3e94aSJung-uk Kim ACPI_FORMAT_UINT64 (Address))); 283a159c266SJung-uk Kim return_ACPI_STATUS (Status); 284a159c266SJung-uk Kim } 285313a0c13SJung-uk Kim 286313a0c13SJung-uk Kim /* 287313a0c13SJung-uk Kim * Optionally do not load any SSDTs from the RSDT/XSDT. This can 288313a0c13SJung-uk Kim * be useful for debugging ACPI problems on some machines. 289313a0c13SJung-uk Kim */ 290313a0c13SJung-uk Kim if (!Reload && 291313a0c13SJung-uk Kim AcpiGbl_DisableSsdtTableInstall && 292313a0c13SJung-uk Kim ACPI_COMPARE_NAME (&NewTableDesc.Signature, ACPI_SIG_SSDT)) 293313a0c13SJung-uk Kim { 2947cf3e94aSJung-uk Kim ACPI_INFO ((AE_INFO, "Ignoring installation of %4.4s at %8.8X%8.8X", 2957cf3e94aSJung-uk Kim NewTableDesc.Signature.Ascii, ACPI_FORMAT_UINT64 (Address))); 296313a0c13SJung-uk Kim goto ReleaseAndExit; 297a159c266SJung-uk Kim } 298a159c266SJung-uk Kim 299313a0c13SJung-uk Kim /* Validate and verify a table before installation */ 300313a0c13SJung-uk Kim 301313a0c13SJung-uk Kim Status = AcpiTbVerifyTempTable (&NewTableDesc, NULL); 302313a0c13SJung-uk Kim if (ACPI_FAILURE (Status)) 303313a0c13SJung-uk Kim { 304313a0c13SJung-uk Kim goto ReleaseAndExit; 305313a0c13SJung-uk Kim } 306313a0c13SJung-uk Kim 307313a0c13SJung-uk Kim if (Reload) 308313a0c13SJung-uk Kim { 309a159c266SJung-uk Kim /* 310a159c266SJung-uk Kim * Validate the incoming table signature. 311a159c266SJung-uk Kim * 312a159c266SJung-uk Kim * 1) Originally, we checked the table signature for "SSDT" or "PSDT". 313a159c266SJung-uk Kim * 2) We added support for OEMx tables, signature "OEM". 314a159c266SJung-uk Kim * 3) Valid tables were encountered with a null signature, so we just 315a159c266SJung-uk Kim * gave up on validating the signature, (05/2008). 316a159c266SJung-uk Kim * 4) We encountered non-AML tables such as the MADT, which caused 317a159c266SJung-uk Kim * interpreter errors and kernel faults. So now, we once again allow 318a159c266SJung-uk Kim * only "SSDT", "OEMx", and now, also a null signature. (05/2011). 319a159c266SJung-uk Kim */ 320313a0c13SJung-uk Kim if ((NewTableDesc.Signature.Ascii[0] != 0x00) && 321313a0c13SJung-uk Kim (!ACPI_COMPARE_NAME (&NewTableDesc.Signature, ACPI_SIG_SSDT)) && 3225ef50723SJung-uk Kim (strncmp (NewTableDesc.Signature.Ascii, "OEM", 3))) 323a159c266SJung-uk Kim { 324e8241eabSJung-uk Kim ACPI_BIOS_ERROR ((AE_INFO, 325e8241eabSJung-uk Kim "Table has invalid signature [%4.4s] (0x%8.8X), " 326e8241eabSJung-uk Kim "must be SSDT or OEMx", 327313a0c13SJung-uk Kim AcpiUtValidAcpiName (NewTableDesc.Signature.Ascii) ? 328313a0c13SJung-uk Kim NewTableDesc.Signature.Ascii : "????", 329313a0c13SJung-uk Kim NewTableDesc.Signature.Integer)); 330a159c266SJung-uk Kim 331313a0c13SJung-uk Kim Status = AE_BAD_SIGNATURE; 332313a0c13SJung-uk Kim goto ReleaseAndExit; 333a159c266SJung-uk Kim } 334a159c266SJung-uk Kim 335a159c266SJung-uk Kim /* Check if table is already registered */ 336a159c266SJung-uk Kim 337a159c266SJung-uk Kim for (i = 0; i < AcpiGbl_RootTableList.CurrentTableCount; ++i) 338a159c266SJung-uk Kim { 339a159c266SJung-uk Kim /* 340a159c266SJung-uk Kim * Check for a table match on the entire table length, 341a159c266SJung-uk Kim * not just the header. 342a159c266SJung-uk Kim */ 343313a0c13SJung-uk Kim if (!AcpiTbCompareTables (&NewTableDesc, i)) 344a159c266SJung-uk Kim { 345a159c266SJung-uk Kim continue; 346a159c266SJung-uk Kim } 347a159c266SJung-uk Kim 348a159c266SJung-uk Kim /* 349a159c266SJung-uk Kim * Note: the current mechanism does not unregister a table if it is 350a159c266SJung-uk Kim * dynamically unloaded. The related namespace entries are deleted, 351a159c266SJung-uk Kim * but the table remains in the root table list. 352a159c266SJung-uk Kim * 353a159c266SJung-uk Kim * The assumption here is that the number of different tables that 354a159c266SJung-uk Kim * will be loaded is actually small, and there is minimal overhead 355a159c266SJung-uk Kim * in just keeping the table in case it is needed again. 356a159c266SJung-uk Kim * 357a159c266SJung-uk Kim * If this assumption changes in the future (perhaps on large 358a159c266SJung-uk Kim * machines with many table load/unload operations), tables will 359a159c266SJung-uk Kim * need to be unregistered when they are unloaded, and slots in the 360a159c266SJung-uk Kim * root table list should be reused when empty. 361a159c266SJung-uk Kim */ 362a159c266SJung-uk Kim if (AcpiGbl_RootTableList.Tables[i].Flags & ACPI_TABLE_IS_LOADED) 363a159c266SJung-uk Kim { 364a159c266SJung-uk Kim /* Table is still loaded, this is an error */ 365a159c266SJung-uk Kim 366a159c266SJung-uk Kim Status = AE_ALREADY_EXISTS; 367313a0c13SJung-uk Kim goto ReleaseAndExit; 368a159c266SJung-uk Kim } 369a159c266SJung-uk Kim else 370a159c266SJung-uk Kim { 371a159c266SJung-uk Kim /* 372313a0c13SJung-uk Kim * Table was unloaded, allow it to be reloaded. 373313a0c13SJung-uk Kim * As we are going to return AE_OK to the caller, we should 374313a0c13SJung-uk Kim * take the responsibility of freeing the input descriptor. 375313a0c13SJung-uk Kim * Refill the input descriptor to ensure 376313a0c13SJung-uk Kim * AcpiTbInstallTableWithOverride() can be called again to 377313a0c13SJung-uk Kim * indicate the re-installation. 378a159c266SJung-uk Kim */ 379313a0c13SJung-uk Kim AcpiTbUninstallTable (&NewTableDesc); 380313a0c13SJung-uk Kim *TableIndex = i; 381313a0c13SJung-uk Kim return_ACPI_STATUS (AE_OK); 382313a0c13SJung-uk Kim } 383313a0c13SJung-uk Kim } 384313a0c13SJung-uk Kim } 385a159c266SJung-uk Kim 386a159c266SJung-uk Kim /* Add the table to the global root table list */ 387a159c266SJung-uk Kim 388*70e6ab8fSJung-uk Kim AcpiTbInstallTableWithOverride (&NewTableDesc, Override, TableIndex); 389a159c266SJung-uk Kim 390313a0c13SJung-uk Kim ReleaseAndExit: 391313a0c13SJung-uk Kim 392313a0c13SJung-uk Kim /* Release the temporary table descriptor */ 393313a0c13SJung-uk Kim 394313a0c13SJung-uk Kim AcpiTbReleaseTempTable (&NewTableDesc); 395a159c266SJung-uk Kim return_ACPI_STATUS (Status); 396a159c266SJung-uk Kim } 397a159c266SJung-uk Kim 398a159c266SJung-uk Kim 399a159c266SJung-uk Kim /******************************************************************************* 400a159c266SJung-uk Kim * 401313a0c13SJung-uk Kim * FUNCTION: AcpiTbOverrideTable 402a159c266SJung-uk Kim * 403313a0c13SJung-uk Kim * PARAMETERS: OldTableDesc - Validated table descriptor to be 404313a0c13SJung-uk Kim * overridden 405a159c266SJung-uk Kim * 406313a0c13SJung-uk Kim * RETURN: None 407a159c266SJung-uk Kim * 408a159c266SJung-uk Kim * DESCRIPTION: Attempt table override by calling the OSL override functions. 409a159c266SJung-uk Kim * Note: If the table is overridden, then the entire new table 410313a0c13SJung-uk Kim * is acquired and returned by this function. 411313a0c13SJung-uk Kim * Before/after invocation, the table descriptor is in a state 412313a0c13SJung-uk Kim * that is "VALIDATED". 413a159c266SJung-uk Kim * 414a159c266SJung-uk Kim ******************************************************************************/ 415a159c266SJung-uk Kim 416313a0c13SJung-uk Kim void 417313a0c13SJung-uk Kim AcpiTbOverrideTable ( 418313a0c13SJung-uk Kim ACPI_TABLE_DESC *OldTableDesc) 419a159c266SJung-uk Kim { 420a159c266SJung-uk Kim ACPI_STATUS Status; 421a159c266SJung-uk Kim char *OverrideType; 422313a0c13SJung-uk Kim ACPI_TABLE_DESC NewTableDesc; 423313a0c13SJung-uk Kim ACPI_TABLE_HEADER *Table; 424313a0c13SJung-uk Kim ACPI_PHYSICAL_ADDRESS Address; 425313a0c13SJung-uk Kim UINT32 Length; 426a159c266SJung-uk Kim 427a159c266SJung-uk Kim 428a159c266SJung-uk Kim /* (1) Attempt logical override (returns a logical address) */ 429a159c266SJung-uk Kim 430313a0c13SJung-uk Kim Status = AcpiOsTableOverride (OldTableDesc->Pointer, &Table); 431313a0c13SJung-uk Kim if (ACPI_SUCCESS (Status) && Table) 432a159c266SJung-uk Kim { 433313a0c13SJung-uk Kim AcpiTbAcquireTempTable (&NewTableDesc, ACPI_PTR_TO_PHYSADDR (Table), 434313a0c13SJung-uk Kim ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL); 435a159c266SJung-uk Kim OverrideType = "Logical"; 436a159c266SJung-uk Kim goto FinishOverride; 437a159c266SJung-uk Kim } 438a159c266SJung-uk Kim 439a159c266SJung-uk Kim /* (2) Attempt physical override (returns a physical address) */ 440a159c266SJung-uk Kim 441313a0c13SJung-uk Kim Status = AcpiOsPhysicalTableOverride (OldTableDesc->Pointer, 442313a0c13SJung-uk Kim &Address, &Length); 443313a0c13SJung-uk Kim if (ACPI_SUCCESS (Status) && Address && Length) 444a159c266SJung-uk Kim { 445313a0c13SJung-uk Kim AcpiTbAcquireTempTable (&NewTableDesc, Address, 446313a0c13SJung-uk Kim ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL); 447a159c266SJung-uk Kim OverrideType = "Physical"; 448a159c266SJung-uk Kim goto FinishOverride; 449a159c266SJung-uk Kim } 450a159c266SJung-uk Kim 451313a0c13SJung-uk Kim return; /* There was no override */ 452a159c266SJung-uk Kim 453a159c266SJung-uk Kim 454a159c266SJung-uk Kim FinishOverride: 455a159c266SJung-uk Kim 456313a0c13SJung-uk Kim /* Validate and verify a table before overriding */ 457a159c266SJung-uk Kim 458313a0c13SJung-uk Kim Status = AcpiTbVerifyTempTable (&NewTableDesc, NULL); 459313a0c13SJung-uk Kim if (ACPI_FAILURE (Status)) 460313a0c13SJung-uk Kim { 461313a0c13SJung-uk Kim return; 462a159c266SJung-uk Kim } 463a159c266SJung-uk Kim 4647cf3e94aSJung-uk Kim ACPI_INFO ((AE_INFO, "%4.4s 0x%8.8X%8.8X" 4657cf3e94aSJung-uk Kim " %s table override, new table: 0x%8.8X%8.8X", 466313a0c13SJung-uk Kim OldTableDesc->Signature.Ascii, 4677cf3e94aSJung-uk Kim ACPI_FORMAT_UINT64 (OldTableDesc->Address), 4687cf3e94aSJung-uk Kim OverrideType, ACPI_FORMAT_UINT64 (NewTableDesc.Address))); 469a159c266SJung-uk Kim 470313a0c13SJung-uk Kim /* We can now uninstall the original table */ 471a159c266SJung-uk Kim 472313a0c13SJung-uk Kim AcpiTbUninstallTable (OldTableDesc); 473a159c266SJung-uk Kim 474313a0c13SJung-uk Kim /* 475313a0c13SJung-uk Kim * Replace the original table descriptor and keep its state as 476313a0c13SJung-uk Kim * "VALIDATED". 477313a0c13SJung-uk Kim */ 478313a0c13SJung-uk Kim AcpiTbInitTableDescriptor (OldTableDesc, NewTableDesc.Address, 479313a0c13SJung-uk Kim NewTableDesc.Flags, NewTableDesc.Pointer); 480313a0c13SJung-uk Kim AcpiTbValidateTempTable (OldTableDesc); 481a159c266SJung-uk Kim 482313a0c13SJung-uk Kim /* Release the temporary table descriptor */ 483a159c266SJung-uk Kim 484313a0c13SJung-uk Kim AcpiTbReleaseTempTable (&NewTableDesc); 485a159c266SJung-uk Kim } 486a159c266SJung-uk Kim 487a159c266SJung-uk Kim 488a159c266SJung-uk Kim /******************************************************************************* 489a159c266SJung-uk Kim * 490313a0c13SJung-uk Kim * FUNCTION: AcpiTbUninstallTable 491a159c266SJung-uk Kim * 492313a0c13SJung-uk Kim * PARAMETERS: TableDesc - Table descriptor 493a159c266SJung-uk Kim * 494a159c266SJung-uk Kim * RETURN: None 495a159c266SJung-uk Kim * 496a159c266SJung-uk Kim * DESCRIPTION: Delete one internal ACPI table 497a159c266SJung-uk Kim * 498a159c266SJung-uk Kim ******************************************************************************/ 499a159c266SJung-uk Kim 500a159c266SJung-uk Kim void 501313a0c13SJung-uk Kim AcpiTbUninstallTable ( 502a159c266SJung-uk Kim ACPI_TABLE_DESC *TableDesc) 503a159c266SJung-uk Kim { 504a159c266SJung-uk Kim 505313a0c13SJung-uk Kim ACPI_FUNCTION_TRACE (TbUninstallTable); 506a159c266SJung-uk Kim 507313a0c13SJung-uk Kim 508313a0c13SJung-uk Kim /* Table must be installed */ 509313a0c13SJung-uk Kim 510313a0c13SJung-uk Kim if (!TableDesc->Address) 511a159c266SJung-uk Kim { 5128ef1a331SJung-uk Kim return_VOID; 513a159c266SJung-uk Kim } 514a159c266SJung-uk Kim 515313a0c13SJung-uk Kim AcpiTbInvalidateTable (TableDesc); 516a159c266SJung-uk Kim 517313a0c13SJung-uk Kim if ((TableDesc->Flags & ACPI_TABLE_ORIGIN_MASK) == 518313a0c13SJung-uk Kim ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL) 519a159c266SJung-uk Kim { 5207cf3e94aSJung-uk Kim ACPI_FREE (ACPI_PHYSADDR_TO_PTR (TableDesc->Address)); 521a159c266SJung-uk Kim } 522a159c266SJung-uk Kim 523313a0c13SJung-uk Kim TableDesc->Address = ACPI_PTR_TO_PHYSADDR (NULL); 524313a0c13SJung-uk Kim return_VOID; 525a159c266SJung-uk Kim } 526