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