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