1 /****************************************************************************** 2 * 3 * Module Name: dswload - Dispatcher first pass namespace load callbacks 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2019, 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 "acparser.h" 47 #include "amlcode.h" 48 #include "acdispat.h" 49 #include "acinterp.h" 50 #include "acnamesp.h" 51 52 #ifdef ACPI_ASL_COMPILER 53 #include "acdisasm.h" 54 #endif 55 56 #define _COMPONENT ACPI_DISPATCHER 57 ACPI_MODULE_NAME ("dswload") 58 59 60 /******************************************************************************* 61 * 62 * FUNCTION: AcpiDsInitCallbacks 63 * 64 * PARAMETERS: WalkState - Current state of the parse tree walk 65 * PassNumber - 1, 2, or 3 66 * 67 * RETURN: Status 68 * 69 * DESCRIPTION: Init walk state callbacks 70 * 71 ******************************************************************************/ 72 73 ACPI_STATUS 74 AcpiDsInitCallbacks ( 75 ACPI_WALK_STATE *WalkState, 76 UINT32 PassNumber) 77 { 78 79 switch (PassNumber) 80 { 81 case 0: 82 83 /* Parse only - caller will setup callbacks */ 84 85 WalkState->ParseFlags = ACPI_PARSE_LOAD_PASS1 | 86 ACPI_PARSE_DELETE_TREE | 87 ACPI_PARSE_DISASSEMBLE; 88 WalkState->DescendingCallback = NULL; 89 WalkState->AscendingCallback = NULL; 90 break; 91 92 case 1: 93 94 /* Load pass 1 */ 95 96 WalkState->ParseFlags = ACPI_PARSE_LOAD_PASS1 | 97 ACPI_PARSE_DELETE_TREE; 98 WalkState->DescendingCallback = AcpiDsLoad1BeginOp; 99 WalkState->AscendingCallback = AcpiDsLoad1EndOp; 100 break; 101 102 case 2: 103 104 /* Load pass 2 */ 105 106 WalkState->ParseFlags = ACPI_PARSE_LOAD_PASS1 | 107 ACPI_PARSE_DELETE_TREE; 108 WalkState->DescendingCallback = AcpiDsLoad2BeginOp; 109 WalkState->AscendingCallback = AcpiDsLoad2EndOp; 110 break; 111 112 case 3: 113 114 /* Execution pass */ 115 116 WalkState->ParseFlags |= ACPI_PARSE_EXECUTE | 117 ACPI_PARSE_DELETE_TREE; 118 WalkState->DescendingCallback = AcpiDsExecBeginOp; 119 WalkState->AscendingCallback = AcpiDsExecEndOp; 120 break; 121 122 default: 123 124 return (AE_BAD_PARAMETER); 125 } 126 127 return (AE_OK); 128 } 129 130 131 /******************************************************************************* 132 * 133 * FUNCTION: AcpiDsLoad1BeginOp 134 * 135 * PARAMETERS: WalkState - Current state of the parse tree walk 136 * OutOp - Where to return op if a new one is created 137 * 138 * RETURN: Status 139 * 140 * DESCRIPTION: Descending callback used during the loading of ACPI tables. 141 * 142 ******************************************************************************/ 143 144 ACPI_STATUS 145 AcpiDsLoad1BeginOp ( 146 ACPI_WALK_STATE *WalkState, 147 ACPI_PARSE_OBJECT **OutOp) 148 { 149 ACPI_PARSE_OBJECT *Op; 150 ACPI_NAMESPACE_NODE *Node; 151 ACPI_STATUS Status; 152 ACPI_OBJECT_TYPE ObjectType; 153 char *Path; 154 UINT32 Flags; 155 156 157 ACPI_FUNCTION_TRACE_PTR (DsLoad1BeginOp, WalkState->Op); 158 159 160 Op = WalkState->Op; 161 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Op=%p State=%p\n", Op, WalkState)); 162 163 /* We are only interested in opcodes that have an associated name */ 164 165 if (Op) 166 { 167 if (!(WalkState->OpInfo->Flags & AML_NAMED)) 168 { 169 *OutOp = Op; 170 return_ACPI_STATUS (AE_OK); 171 } 172 173 /* Check if this object has already been installed in the namespace */ 174 175 if (Op->Common.Node) 176 { 177 *OutOp = Op; 178 return_ACPI_STATUS (AE_OK); 179 } 180 } 181 182 Path = AcpiPsGetNextNamestring (&WalkState->ParserState); 183 184 /* Map the raw opcode into an internal object type */ 185 186 ObjectType = WalkState->OpInfo->ObjectType; 187 188 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, 189 "State=%p Op=%p [%s]\n", WalkState, Op, 190 AcpiUtGetTypeName (ObjectType))); 191 192 switch (WalkState->Opcode) 193 { 194 case AML_SCOPE_OP: 195 /* 196 * The target name of the Scope() operator must exist at this point so 197 * that we can actually open the scope to enter new names underneath it. 198 * Allow search-to-root for single namesegs. 199 */ 200 Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ObjectType, 201 ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT, WalkState, &(Node)); 202 #ifdef ACPI_ASL_COMPILER 203 if (Status == AE_NOT_FOUND) 204 { 205 /* 206 * Table disassembly: 207 * Target of Scope() not found. Generate an External for it, and 208 * insert the name into the namespace. 209 */ 210 AcpiDmAddOpToExternalList (Op, Path, ACPI_TYPE_DEVICE, 0, 0); 211 Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ObjectType, 212 ACPI_IMODE_LOAD_PASS1, ACPI_NS_SEARCH_PARENT, 213 WalkState, &Node); 214 } 215 #endif 216 if (ACPI_FAILURE (Status)) 217 { 218 ACPI_ERROR_NAMESPACE (WalkState->ScopeInfo, Path, Status); 219 return_ACPI_STATUS (Status); 220 } 221 222 /* 223 * Check to make sure that the target is 224 * one of the opcodes that actually opens a scope 225 */ 226 switch (Node->Type) 227 { 228 case ACPI_TYPE_ANY: 229 case ACPI_TYPE_LOCAL_SCOPE: /* Scope */ 230 case ACPI_TYPE_DEVICE: 231 case ACPI_TYPE_POWER: 232 case ACPI_TYPE_PROCESSOR: 233 case ACPI_TYPE_THERMAL: 234 235 /* These are acceptable types */ 236 break; 237 238 case ACPI_TYPE_INTEGER: 239 case ACPI_TYPE_STRING: 240 case ACPI_TYPE_BUFFER: 241 /* 242 * These types we will allow, but we will change the type. 243 * This enables some existing code of the form: 244 * 245 * Name (DEB, 0) 246 * Scope (DEB) { ... } 247 * 248 * Note: silently change the type here. On the second pass, 249 * we will report a warning 250 */ 251 ACPI_DEBUG_PRINT ((ACPI_DB_INFO, 252 "Type override - [%4.4s] had invalid type (%s) " 253 "for Scope operator, changed to type ANY\n", 254 AcpiUtGetNodeName (Node), AcpiUtGetTypeName (Node->Type))); 255 256 Node->Type = ACPI_TYPE_ANY; 257 WalkState->ScopeInfo->Common.Value = ACPI_TYPE_ANY; 258 break; 259 260 case ACPI_TYPE_METHOD: 261 /* 262 * Allow scope change to root during execution of module-level 263 * code. Root is typed METHOD during this time. 264 */ 265 if ((Node == AcpiGbl_RootNode) && 266 (WalkState->ParseFlags & ACPI_PARSE_MODULE_LEVEL)) 267 { 268 break; 269 } 270 271 /*lint -fallthrough */ 272 273 default: 274 275 /* All other types are an error */ 276 277 ACPI_ERROR ((AE_INFO, 278 "Invalid type (%s) for target of " 279 "Scope operator [%4.4s] (Cannot override)", 280 AcpiUtGetTypeName (Node->Type), AcpiUtGetNodeName (Node))); 281 282 return_ACPI_STATUS (AE_AML_OPERAND_TYPE); 283 } 284 break; 285 286 default: 287 /* 288 * For all other named opcodes, we will enter the name into 289 * the namespace. 290 * 291 * Setup the search flags. 292 * Since we are entering a name into the namespace, we do not want to 293 * enable the search-to-root upsearch. 294 * 295 * There are only two conditions where it is acceptable that the name 296 * already exists: 297 * 1) the Scope() operator can reopen a scoping object that was 298 * previously defined (Scope, Method, Device, etc.) 299 * 2) Whenever we are parsing a deferred opcode (OpRegion, Buffer, 300 * BufferField, or Package), the name of the object is already 301 * in the namespace. 302 */ 303 if (WalkState->DeferredNode) 304 { 305 /* This name is already in the namespace, get the node */ 306 307 Node = WalkState->DeferredNode; 308 Status = AE_OK; 309 break; 310 } 311 312 /* 313 * If we are executing a method, do not create any namespace objects 314 * during the load phase, only during execution. 315 */ 316 if (WalkState->MethodNode) 317 { 318 Node = NULL; 319 Status = AE_OK; 320 break; 321 } 322 323 Flags = ACPI_NS_NO_UPSEARCH; 324 if ((WalkState->Opcode != AML_SCOPE_OP) && 325 (!(WalkState->ParseFlags & ACPI_PARSE_DEFERRED_OP))) 326 { 327 if (WalkState->NamespaceOverride) 328 { 329 Flags |= ACPI_NS_OVERRIDE_IF_FOUND; 330 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "[%s] Override allowed\n", 331 AcpiUtGetTypeName (ObjectType))); 332 } 333 else 334 { 335 Flags |= ACPI_NS_ERROR_IF_FOUND; 336 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "[%s] Cannot already exist\n", 337 AcpiUtGetTypeName (ObjectType))); 338 } 339 } 340 else 341 { 342 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, 343 "[%s] Both Find or Create allowed\n", 344 AcpiUtGetTypeName (ObjectType))); 345 } 346 347 /* 348 * Enter the named type into the internal namespace. We enter the name 349 * as we go downward in the parse tree. Any necessary subobjects that 350 * involve arguments to the opcode must be created as we go back up the 351 * parse tree later. 352 */ 353 Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ObjectType, 354 ACPI_IMODE_LOAD_PASS1, Flags, WalkState, &Node); 355 if (ACPI_FAILURE (Status)) 356 { 357 if (Status == AE_ALREADY_EXISTS) 358 { 359 /* The name already exists in this scope */ 360 361 if (Node->Flags & ANOBJ_IS_EXTERNAL) 362 { 363 /* 364 * Allow one create on an object or segment that was 365 * previously declared External 366 */ 367 Node->Flags &= ~ANOBJ_IS_EXTERNAL; 368 Node->Type = (UINT8) ObjectType; 369 370 /* Just retyped a node, probably will need to open a scope */ 371 372 if (AcpiNsOpensScope (ObjectType)) 373 { 374 Status = AcpiDsScopeStackPush ( 375 Node, ObjectType, WalkState); 376 if (ACPI_FAILURE (Status)) 377 { 378 return_ACPI_STATUS (Status); 379 } 380 } 381 382 Status = AE_OK; 383 } 384 } 385 386 if (ACPI_FAILURE (Status)) 387 { 388 ACPI_ERROR_NAMESPACE (WalkState->ScopeInfo, Path, Status); 389 return_ACPI_STATUS (Status); 390 } 391 } 392 break; 393 } 394 395 /* Common exit */ 396 397 if (!Op) 398 { 399 /* Create a new op */ 400 401 Op = AcpiPsAllocOp (WalkState->Opcode, WalkState->Aml); 402 if (!Op) 403 { 404 return_ACPI_STATUS (AE_NO_MEMORY); 405 } 406 } 407 408 /* Initialize the op */ 409 410 #ifdef ACPI_CONSTANT_EVAL_ONLY 411 Op->Named.Path = Path; 412 #endif 413 414 if (Node) 415 { 416 /* 417 * Put the Node in the "op" object that the parser uses, so we 418 * can get it again quickly when this scope is closed 419 */ 420 Op->Common.Node = Node; 421 Op->Named.Name = Node->Name.Integer; 422 } 423 424 AcpiPsAppendArg (AcpiPsGetParentScope (&WalkState->ParserState), Op); 425 *OutOp = Op; 426 return_ACPI_STATUS (Status); 427 } 428 429 430 /******************************************************************************* 431 * 432 * FUNCTION: AcpiDsLoad1EndOp 433 * 434 * PARAMETERS: WalkState - Current state of the parse tree walk 435 * 436 * RETURN: Status 437 * 438 * DESCRIPTION: Ascending callback used during the loading of the namespace, 439 * both control methods and everything else. 440 * 441 ******************************************************************************/ 442 443 ACPI_STATUS 444 AcpiDsLoad1EndOp ( 445 ACPI_WALK_STATE *WalkState) 446 { 447 ACPI_PARSE_OBJECT *Op; 448 ACPI_OBJECT_TYPE ObjectType; 449 ACPI_STATUS Status = AE_OK; 450 451 #ifdef ACPI_ASL_COMPILER 452 UINT8 ParamCount; 453 #endif 454 455 456 ACPI_FUNCTION_TRACE (DsLoad1EndOp); 457 458 459 Op = WalkState->Op; 460 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Op=%p State=%p\n", Op, WalkState)); 461 462 /* 463 * Disassembler: handle create field operators here. 464 * 465 * CreateBufferField is a deferred op that is typically processed in load 466 * pass 2. However, disassembly of control method contents walk the parse 467 * tree with ACPI_PARSE_LOAD_PASS1 and AML_CREATE operators are processed 468 * in a later walk. This is a problem when there is a control method that 469 * has the same name as the AML_CREATE object. In this case, any use of the 470 * name segment will be detected as a method call rather than a reference 471 * to a buffer field. 472 * 473 * This earlier creation during disassembly solves this issue by inserting 474 * the named object in the ACPI namespace so that references to this name 475 * would be a name string rather than a method call. 476 */ 477 if ((WalkState->ParseFlags & ACPI_PARSE_DISASSEMBLE) && 478 (WalkState->OpInfo->Flags & AML_CREATE)) 479 { 480 Status = AcpiDsCreateBufferField (Op, WalkState); 481 return_ACPI_STATUS (Status); 482 } 483 484 /* We are only interested in opcodes that have an associated name */ 485 486 if (!(WalkState->OpInfo->Flags & (AML_NAMED | AML_FIELD))) 487 { 488 return_ACPI_STATUS (AE_OK); 489 } 490 491 /* Get the object type to determine if we should pop the scope */ 492 493 ObjectType = WalkState->OpInfo->ObjectType; 494 495 if (WalkState->OpInfo->Flags & AML_FIELD) 496 { 497 /* 498 * If we are executing a method, do not create any namespace objects 499 * during the load phase, only during execution. 500 */ 501 if (!WalkState->MethodNode) 502 { 503 if (WalkState->Opcode == AML_FIELD_OP || 504 WalkState->Opcode == AML_BANK_FIELD_OP || 505 WalkState->Opcode == AML_INDEX_FIELD_OP) 506 { 507 Status = AcpiDsInitFieldObjects (Op, WalkState); 508 } 509 } 510 return_ACPI_STATUS (Status); 511 } 512 513 /* 514 * If we are executing a method, do not create any namespace objects 515 * during the load phase, only during execution. 516 */ 517 if (!WalkState->MethodNode) 518 { 519 if (Op->Common.AmlOpcode == AML_REGION_OP) 520 { 521 Status = AcpiExCreateRegion (Op->Named.Data, Op->Named.Length, 522 (ACPI_ADR_SPACE_TYPE) 523 ((Op->Common.Value.Arg)->Common.Value.Integer), 524 WalkState); 525 if (ACPI_FAILURE (Status)) 526 { 527 return_ACPI_STATUS (Status); 528 } 529 } 530 else if (Op->Common.AmlOpcode == AML_DATA_REGION_OP) 531 { 532 Status = AcpiExCreateRegion (Op->Named.Data, Op->Named.Length, 533 ACPI_ADR_SPACE_DATA_TABLE, WalkState); 534 if (ACPI_FAILURE (Status)) 535 { 536 return_ACPI_STATUS (Status); 537 } 538 } 539 } 540 541 if (Op->Common.AmlOpcode == AML_NAME_OP) 542 { 543 /* For Name opcode, get the object type from the argument */ 544 545 if (Op->Common.Value.Arg) 546 { 547 ObjectType = (AcpiPsGetOpcodeInfo ( 548 (Op->Common.Value.Arg)->Common.AmlOpcode))->ObjectType; 549 550 /* Set node type if we have a namespace node */ 551 552 if (Op->Common.Node) 553 { 554 Op->Common.Node->Type = (UINT8) ObjectType; 555 } 556 } 557 } 558 559 #ifdef ACPI_ASL_COMPILER 560 /* 561 * For external opcode, get the object type from the argument and 562 * get the parameter count from the argument's next. 563 */ 564 if (AcpiGbl_DisasmFlag && 565 Op->Common.Node && 566 Op->Common.AmlOpcode == AML_EXTERNAL_OP) 567 { 568 /* 569 * Note, if this external is not a method 570 * Op->Common.Value.Arg->Common.Next->Common.Value.Integer == 0 571 * Therefore, ParamCount will be 0. 572 */ 573 ParamCount = (UINT8) Op->Common.Value.Arg->Common.Next->Common.Value.Integer; 574 ObjectType = (UINT8) Op->Common.Value.Arg->Common.Value.Integer; 575 Op->Common.Node->Flags |= ANOBJ_IS_EXTERNAL; 576 Op->Common.Node->Type = (UINT8) ObjectType; 577 578 AcpiDmCreateSubobjectForExternal ((UINT8)ObjectType, 579 &Op->Common.Node, ParamCount); 580 581 /* 582 * Add the external to the external list because we may be 583 * emitting code based off of the items within the external list. 584 */ 585 AcpiDmAddOpToExternalList (Op, Op->Named.Path, (UINT8)ObjectType, ParamCount, 586 ACPI_EXT_ORIGIN_FROM_OPCODE | ACPI_EXT_RESOLVED_REFERENCE); 587 } 588 #endif 589 590 /* 591 * If we are executing a method, do not create any namespace objects 592 * during the load phase, only during execution. 593 */ 594 if (!WalkState->MethodNode) 595 { 596 if (Op->Common.AmlOpcode == AML_METHOD_OP) 597 { 598 /* 599 * MethodOp PkgLength NameString MethodFlags TermList 600 * 601 * Note: We must create the method node/object pair as soon as we 602 * see the method declaration. This allows later pass1 parsing 603 * of invocations of the method (need to know the number of 604 * arguments.) 605 */ 606 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, 607 "LOADING-Method: State=%p Op=%p NamedObj=%p\n", 608 WalkState, Op, Op->Named.Node)); 609 610 if (!AcpiNsGetAttachedObject (Op->Named.Node)) 611 { 612 WalkState->Operands[0] = ACPI_CAST_PTR (void, Op->Named.Node); 613 WalkState->NumOperands = 1; 614 615 Status = AcpiDsCreateOperands ( 616 WalkState, Op->Common.Value.Arg); 617 if (ACPI_SUCCESS (Status)) 618 { 619 Status = AcpiExCreateMethod (Op->Named.Data, 620 Op->Named.Length, WalkState); 621 } 622 623 WalkState->Operands[0] = NULL; 624 WalkState->NumOperands = 0; 625 626 if (ACPI_FAILURE (Status)) 627 { 628 return_ACPI_STATUS (Status); 629 } 630 } 631 } 632 } 633 634 /* Pop the scope stack (only if loading a table) */ 635 636 if (!WalkState->MethodNode && 637 Op->Common.AmlOpcode != AML_EXTERNAL_OP && 638 AcpiNsOpensScope (ObjectType)) 639 { 640 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "(%s): Popping scope for Op %p\n", 641 AcpiUtGetTypeName (ObjectType), Op)); 642 643 Status = AcpiDsScopeStackPop (WalkState); 644 } 645 646 return_ACPI_STATUS (Status); 647 } 648