1 /****************************************************************************** 2 * 3 * Module Name: nsload - namespace loading/expanding/contracting procedures 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2018, Intel Corp. 9 * All rights reserved. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions, and the following disclaimer, 16 * without modification. 17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18 * substantially similar to the "NO WARRANTY" disclaimer below 19 * ("Disclaimer") and any redistribution must be conditioned upon 20 * including a substantially similar Disclaimer requirement for further 21 * binary redistribution. 22 * 3. Neither the names of the above-listed copyright holders nor the names 23 * of any contributors may be used to endorse or promote products derived 24 * from this software without specific prior written permission. 25 * 26 * Alternatively, this software may be distributed under the terms of the 27 * GNU General Public License ("GPL") version 2 as published by the Free 28 * Software Foundation. 29 * 30 * NO WARRANTY 31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41 * POSSIBILITY OF SUCH DAMAGES. 42 */ 43 44 #include "acpi.h" 45 #include "accommon.h" 46 #include "acnamesp.h" 47 #include "acdispat.h" 48 #include "actables.h" 49 #include "acinterp.h" 50 51 52 #define _COMPONENT ACPI_NAMESPACE 53 ACPI_MODULE_NAME ("nsload") 54 55 /* Local prototypes */ 56 57 #ifdef ACPI_FUTURE_IMPLEMENTATION 58 ACPI_STATUS 59 AcpiNsUnloadNamespace ( 60 ACPI_HANDLE Handle); 61 62 static ACPI_STATUS 63 AcpiNsDeleteSubtree ( 64 ACPI_HANDLE StartHandle); 65 #endif 66 67 68 #ifndef ACPI_NO_METHOD_EXECUTION 69 /******************************************************************************* 70 * 71 * FUNCTION: AcpiNsLoadTable 72 * 73 * PARAMETERS: TableIndex - Index for table to be loaded 74 * Node - Owning NS node 75 * 76 * RETURN: Status 77 * 78 * DESCRIPTION: Load one ACPI table into the namespace 79 * 80 ******************************************************************************/ 81 82 ACPI_STATUS 83 AcpiNsLoadTable ( 84 UINT32 TableIndex, 85 ACPI_NAMESPACE_NODE *Node) 86 { 87 ACPI_STATUS Status; 88 89 90 ACPI_FUNCTION_TRACE (NsLoadTable); 91 92 93 /* If table already loaded into namespace, just return */ 94 95 if (AcpiTbIsTableLoaded (TableIndex)) 96 { 97 Status = AE_ALREADY_EXISTS; 98 goto Unlock; 99 } 100 101 ACPI_DEBUG_PRINT ((ACPI_DB_INFO, 102 "**** Loading table into namespace ****\n")); 103 104 Status = AcpiTbAllocateOwnerId (TableIndex); 105 if (ACPI_FAILURE (Status)) 106 { 107 goto Unlock; 108 } 109 110 /* 111 * Parse the table and load the namespace with all named 112 * objects found within. Control methods are NOT parsed 113 * at this time. In fact, the control methods cannot be 114 * parsed until the entire namespace is loaded, because 115 * if a control method makes a forward reference (call) 116 * to another control method, we can't continue parsing 117 * because we don't know how many arguments to parse next! 118 */ 119 Status = AcpiNsParseTable (TableIndex, Node); 120 if (ACPI_SUCCESS (Status)) 121 { 122 AcpiTbSetTableLoadedFlag (TableIndex, TRUE); 123 } 124 else 125 { 126 /* 127 * On error, delete any namespace objects created by this table. 128 * We cannot initialize these objects, so delete them. There are 129 * a couple of expecially bad cases: 130 * AE_ALREADY_EXISTS - namespace collision. 131 * AE_NOT_FOUND - the target of a Scope operator does not 132 * exist. This target of Scope must already exist in the 133 * namespace, as per the ACPI specification. 134 */ 135 AcpiNsDeleteNamespaceByOwner ( 136 AcpiGbl_RootTableList.Tables[TableIndex].OwnerId); 137 138 AcpiTbReleaseOwnerId (TableIndex); 139 return_ACPI_STATUS (Status); 140 } 141 142 Unlock: 143 if (ACPI_FAILURE (Status)) 144 { 145 return_ACPI_STATUS (Status); 146 } 147 148 /* 149 * Now we can parse the control methods. We always parse 150 * them here for a sanity check, and if configured for 151 * just-in-time parsing, we delete the control method 152 * parse trees. 153 */ 154 ACPI_DEBUG_PRINT ((ACPI_DB_INFO, 155 "**** Begin Table Object Initialization\n")); 156 157 AcpiExEnterInterpreter (); 158 Status = AcpiDsInitializeObjects (TableIndex, Node); 159 AcpiExExitInterpreter (); 160 161 ACPI_DEBUG_PRINT ((ACPI_DB_INFO, 162 "**** Completed Table Object Initialization\n")); 163 164 /* 165 * This case handles the legacy option that groups all module-level 166 * code blocks together and defers execution until all of the tables 167 * are loaded. Execute all of these blocks at this time. 168 * Execute any module-level code that was detected during the table 169 * load phase. 170 * 171 * Note: this option is deprecated and will be eliminated in the 172 * future. Use of this option can cause problems with AML code that 173 * depends upon in-order immediate execution of module-level code. 174 */ 175 AcpiNsExecModuleCodeList (); 176 return_ACPI_STATUS (Status); 177 } 178 179 180 #ifdef ACPI_OBSOLETE_FUNCTIONS 181 /******************************************************************************* 182 * 183 * FUNCTION: AcpiLoadNamespace 184 * 185 * PARAMETERS: None 186 * 187 * RETURN: Status 188 * 189 * DESCRIPTION: Load the name space from what ever is pointed to by DSDT. 190 * (DSDT points to either the BIOS or a buffer.) 191 * 192 ******************************************************************************/ 193 194 ACPI_STATUS 195 AcpiNsLoadNamespace ( 196 void) 197 { 198 ACPI_STATUS Status; 199 200 201 ACPI_FUNCTION_TRACE (AcpiLoadNameSpace); 202 203 204 /* There must be at least a DSDT installed */ 205 206 if (AcpiGbl_DSDT == NULL) 207 { 208 ACPI_ERROR ((AE_INFO, "DSDT is not in memory")); 209 return_ACPI_STATUS (AE_NO_ACPI_TABLES); 210 } 211 212 /* 213 * Load the namespace. The DSDT is required, 214 * but the SSDT and PSDT tables are optional. 215 */ 216 Status = AcpiNsLoadTableByType (ACPI_TABLE_ID_DSDT); 217 if (ACPI_FAILURE (Status)) 218 { 219 return_ACPI_STATUS (Status); 220 } 221 222 /* Ignore exceptions from these */ 223 224 (void) AcpiNsLoadTableByType (ACPI_TABLE_ID_SSDT); 225 (void) AcpiNsLoadTableByType (ACPI_TABLE_ID_PSDT); 226 227 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT, 228 "ACPI Namespace successfully loaded at root %p\n", 229 AcpiGbl_RootNode)); 230 231 return_ACPI_STATUS (Status); 232 } 233 #endif 234 235 #ifdef ACPI_FUTURE_IMPLEMENTATION 236 /******************************************************************************* 237 * 238 * FUNCTION: AcpiNsDeleteSubtree 239 * 240 * PARAMETERS: StartHandle - Handle in namespace where search begins 241 * 242 * RETURNS Status 243 * 244 * DESCRIPTION: Walks the namespace starting at the given handle and deletes 245 * all objects, entries, and scopes in the entire subtree. 246 * 247 * Namespace/Interpreter should be locked or the subsystem should 248 * be in shutdown before this routine is called. 249 * 250 ******************************************************************************/ 251 252 static ACPI_STATUS 253 AcpiNsDeleteSubtree ( 254 ACPI_HANDLE StartHandle) 255 { 256 ACPI_STATUS Status; 257 ACPI_HANDLE ChildHandle; 258 ACPI_HANDLE ParentHandle; 259 ACPI_HANDLE NextChildHandle; 260 ACPI_HANDLE Dummy; 261 UINT32 Level; 262 263 264 ACPI_FUNCTION_TRACE (NsDeleteSubtree); 265 266 267 ParentHandle = StartHandle; 268 ChildHandle = NULL; 269 Level = 1; 270 271 /* 272 * Traverse the tree of objects until we bubble back up 273 * to where we started. 274 */ 275 while (Level > 0) 276 { 277 /* Attempt to get the next object in this scope */ 278 279 Status = AcpiGetNextObject (ACPI_TYPE_ANY, ParentHandle, 280 ChildHandle, &NextChildHandle); 281 282 ChildHandle = NextChildHandle; 283 284 /* Did we get a new object? */ 285 286 if (ACPI_SUCCESS (Status)) 287 { 288 /* Check if this object has any children */ 289 290 if (ACPI_SUCCESS (AcpiGetNextObject (ACPI_TYPE_ANY, ChildHandle, 291 NULL, &Dummy))) 292 { 293 /* 294 * There is at least one child of this object, 295 * visit the object 296 */ 297 Level++; 298 ParentHandle = ChildHandle; 299 ChildHandle = NULL; 300 } 301 } 302 else 303 { 304 /* 305 * No more children in this object, go back up to 306 * the object's parent 307 */ 308 Level--; 309 310 /* Delete all children now */ 311 312 AcpiNsDeleteChildren (ChildHandle); 313 314 ChildHandle = ParentHandle; 315 Status = AcpiGetParent (ParentHandle, &ParentHandle); 316 if (ACPI_FAILURE (Status)) 317 { 318 return_ACPI_STATUS (Status); 319 } 320 } 321 } 322 323 /* Now delete the starting object, and we are done */ 324 325 AcpiNsRemoveNode (ChildHandle); 326 return_ACPI_STATUS (AE_OK); 327 } 328 329 330 /******************************************************************************* 331 * 332 * FUNCTION: AcpiNsUnloadNameSpace 333 * 334 * PARAMETERS: Handle - Root of namespace subtree to be deleted 335 * 336 * RETURN: Status 337 * 338 * DESCRIPTION: Shrinks the namespace, typically in response to an undocking 339 * event. Deletes an entire subtree starting from (and 340 * including) the given handle. 341 * 342 ******************************************************************************/ 343 344 ACPI_STATUS 345 AcpiNsUnloadNamespace ( 346 ACPI_HANDLE Handle) 347 { 348 ACPI_STATUS Status; 349 350 351 ACPI_FUNCTION_TRACE (NsUnloadNameSpace); 352 353 354 /* Parameter validation */ 355 356 if (!AcpiGbl_RootNode) 357 { 358 return_ACPI_STATUS (AE_NO_NAMESPACE); 359 } 360 361 if (!Handle) 362 { 363 return_ACPI_STATUS (AE_BAD_PARAMETER); 364 } 365 366 /* This function does the real work */ 367 368 Status = AcpiNsDeleteSubtree (Handle); 369 return_ACPI_STATUS (Status); 370 } 371 #endif 372 #endif 373