128c506b8Sjruoho /****************************************************************************** 228c506b8Sjruoho * 328c506b8Sjruoho * Module Name: dswload - Dispatcher namespace load callbacks 428c506b8Sjruoho * 528c506b8Sjruoho *****************************************************************************/ 628c506b8Sjruoho 7124f4c82Sjruoho /* 8660602a8Schristos * Copyright (C) 2000 - 2017, Intel Corp. 928c506b8Sjruoho * All rights reserved. 1028c506b8Sjruoho * 11124f4c82Sjruoho * Redistribution and use in source and binary forms, with or without 12124f4c82Sjruoho * modification, are permitted provided that the following conditions 13124f4c82Sjruoho * are met: 14124f4c82Sjruoho * 1. Redistributions of source code must retain the above copyright 15124f4c82Sjruoho * notice, this list of conditions, and the following disclaimer, 16124f4c82Sjruoho * without modification. 17124f4c82Sjruoho * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18124f4c82Sjruoho * substantially similar to the "NO WARRANTY" disclaimer below 19124f4c82Sjruoho * ("Disclaimer") and any redistribution must be conditioned upon 20124f4c82Sjruoho * including a substantially similar Disclaimer requirement for further 21124f4c82Sjruoho * binary redistribution. 22124f4c82Sjruoho * 3. Neither the names of the above-listed copyright holders nor the names 23124f4c82Sjruoho * of any contributors may be used to endorse or promote products derived 24124f4c82Sjruoho * from this software without specific prior written permission. 2528c506b8Sjruoho * 26124f4c82Sjruoho * Alternatively, this software may be distributed under the terms of the 27124f4c82Sjruoho * GNU General Public License ("GPL") version 2 as published by the Free 28124f4c82Sjruoho * Software Foundation. 2928c506b8Sjruoho * 30124f4c82Sjruoho * NO WARRANTY 31124f4c82Sjruoho * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32124f4c82Sjruoho * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33124f4c82Sjruoho * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34124f4c82Sjruoho * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35124f4c82Sjruoho * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36124f4c82Sjruoho * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37124f4c82Sjruoho * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38124f4c82Sjruoho * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39124f4c82Sjruoho * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40124f4c82Sjruoho * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41124f4c82Sjruoho * POSSIBILITY OF SUCH DAMAGES. 42124f4c82Sjruoho */ 4328c506b8Sjruoho 4428c506b8Sjruoho #include "aslcompiler.h" 4528c506b8Sjruoho #include "amlcode.h" 4628c506b8Sjruoho #include "acdispat.h" 4728c506b8Sjruoho #include "acnamesp.h" 4828c506b8Sjruoho 4928c506b8Sjruoho #include "aslcompiler.y.h" 5028c506b8Sjruoho 5128c506b8Sjruoho #define _COMPONENT ACPI_COMPILER 5228c506b8Sjruoho ACPI_MODULE_NAME ("aslload") 5328c506b8Sjruoho 5428c506b8Sjruoho /* Local prototypes */ 5528c506b8Sjruoho 5628c506b8Sjruoho static ACPI_STATUS 5728c506b8Sjruoho LdLoadFieldElements ( 5828c506b8Sjruoho ACPI_PARSE_OBJECT *Op, 5928c506b8Sjruoho ACPI_WALK_STATE *WalkState); 6028c506b8Sjruoho 6128c506b8Sjruoho static ACPI_STATUS 6228c506b8Sjruoho LdLoadResourceElements ( 6328c506b8Sjruoho ACPI_PARSE_OBJECT *Op, 6428c506b8Sjruoho ACPI_WALK_STATE *WalkState); 6528c506b8Sjruoho 6628c506b8Sjruoho static ACPI_STATUS 6728c506b8Sjruoho LdNamespace1Begin ( 6828c506b8Sjruoho ACPI_PARSE_OBJECT *Op, 6928c506b8Sjruoho UINT32 Level, 7028c506b8Sjruoho void *Context); 7128c506b8Sjruoho 7228c506b8Sjruoho static ACPI_STATUS 7328c506b8Sjruoho LdNamespace2Begin ( 7428c506b8Sjruoho ACPI_PARSE_OBJECT *Op, 7528c506b8Sjruoho UINT32 Level, 7628c506b8Sjruoho void *Context); 7728c506b8Sjruoho 7828c506b8Sjruoho static ACPI_STATUS 7928c506b8Sjruoho LdCommonNamespaceEnd ( 8028c506b8Sjruoho ACPI_PARSE_OBJECT *Op, 8128c506b8Sjruoho UINT32 Level, 8228c506b8Sjruoho void *Context); 8328c506b8Sjruoho 8428c506b8Sjruoho 8528c506b8Sjruoho /******************************************************************************* 8628c506b8Sjruoho * 8728c506b8Sjruoho * FUNCTION: LdLoadNamespace 8828c506b8Sjruoho * 8928c506b8Sjruoho * PARAMETERS: RootOp - Root of the parse tree 9028c506b8Sjruoho * 9128c506b8Sjruoho * RETURN: Status 9228c506b8Sjruoho * 9328c506b8Sjruoho * DESCRIPTION: Perform a walk of the parse tree that in turn loads all of the 9428c506b8Sjruoho * named ASL/AML objects into the namespace. The namespace is 9528c506b8Sjruoho * constructed in order to resolve named references and references 9628c506b8Sjruoho * to named fields within resource templates/descriptors. 9728c506b8Sjruoho * 9828c506b8Sjruoho ******************************************************************************/ 9928c506b8Sjruoho 10028c506b8Sjruoho ACPI_STATUS 10128c506b8Sjruoho LdLoadNamespace ( 10228c506b8Sjruoho ACPI_PARSE_OBJECT *RootOp) 10328c506b8Sjruoho { 10428c506b8Sjruoho ACPI_WALK_STATE *WalkState; 10528c506b8Sjruoho 10628c506b8Sjruoho 10728c506b8Sjruoho /* Create a new walk state */ 10828c506b8Sjruoho 10928c506b8Sjruoho WalkState = AcpiDsCreateWalkState (0, NULL, NULL, NULL); 11028c506b8Sjruoho if (!WalkState) 11128c506b8Sjruoho { 112ff4a156dSchristos return (AE_NO_MEMORY); 11328c506b8Sjruoho } 11428c506b8Sjruoho 11528c506b8Sjruoho /* Walk the entire parse tree, first pass */ 11628c506b8Sjruoho 11728c506b8Sjruoho TrWalkParseTree (RootOp, ASL_WALK_VISIT_TWICE, LdNamespace1Begin, 11828c506b8Sjruoho LdCommonNamespaceEnd, WalkState); 11928c506b8Sjruoho 12028c506b8Sjruoho /* Second pass to handle forward references */ 12128c506b8Sjruoho 12228c506b8Sjruoho TrWalkParseTree (RootOp, ASL_WALK_VISIT_TWICE, LdNamespace2Begin, 12328c506b8Sjruoho LdCommonNamespaceEnd, WalkState); 12428c506b8Sjruoho 12528c506b8Sjruoho /* Dump the namespace if debug is enabled */ 12628c506b8Sjruoho 12728c506b8Sjruoho AcpiNsDumpTables (ACPI_NS_ALL, ACPI_UINT32_MAX); 128414ef032Schristos ACPI_FREE (WalkState); 129ff4a156dSchristos return (AE_OK); 13028c506b8Sjruoho } 13128c506b8Sjruoho 13228c506b8Sjruoho 13328c506b8Sjruoho /******************************************************************************* 13428c506b8Sjruoho * 13528c506b8Sjruoho * FUNCTION: LdLoadFieldElements 13628c506b8Sjruoho * 13728c506b8Sjruoho * PARAMETERS: Op - Parent node (Field) 13828c506b8Sjruoho * WalkState - Current walk state 13928c506b8Sjruoho * 14028c506b8Sjruoho * RETURN: Status 14128c506b8Sjruoho * 14228c506b8Sjruoho * DESCRIPTION: Enter the named elements of the field (children of the parent) 14328c506b8Sjruoho * into the namespace. 14428c506b8Sjruoho * 14528c506b8Sjruoho ******************************************************************************/ 14628c506b8Sjruoho 14728c506b8Sjruoho static ACPI_STATUS 14828c506b8Sjruoho LdLoadFieldElements ( 14928c506b8Sjruoho ACPI_PARSE_OBJECT *Op, 15028c506b8Sjruoho ACPI_WALK_STATE *WalkState) 15128c506b8Sjruoho { 15228c506b8Sjruoho ACPI_PARSE_OBJECT *Child = NULL; 15328c506b8Sjruoho ACPI_NAMESPACE_NODE *Node; 15428c506b8Sjruoho ACPI_STATUS Status; 15528c506b8Sjruoho 15628c506b8Sjruoho 15728c506b8Sjruoho /* Get the first named field element */ 15828c506b8Sjruoho 15928c506b8Sjruoho switch (Op->Asl.AmlOpcode) 16028c506b8Sjruoho { 16128c506b8Sjruoho case AML_BANK_FIELD_OP: 16228c506b8Sjruoho 16328c506b8Sjruoho Child = UtGetArg (Op, 6); 16428c506b8Sjruoho break; 16528c506b8Sjruoho 16628c506b8Sjruoho case AML_INDEX_FIELD_OP: 16728c506b8Sjruoho 16828c506b8Sjruoho Child = UtGetArg (Op, 5); 16928c506b8Sjruoho break; 17028c506b8Sjruoho 17128c506b8Sjruoho case AML_FIELD_OP: 17228c506b8Sjruoho 17328c506b8Sjruoho Child = UtGetArg (Op, 4); 17428c506b8Sjruoho break; 17528c506b8Sjruoho 17628c506b8Sjruoho default: 177ff4a156dSchristos 17828c506b8Sjruoho /* No other opcodes should arrive here */ 179ff4a156dSchristos 18028c506b8Sjruoho return (AE_BAD_PARAMETER); 18128c506b8Sjruoho } 18228c506b8Sjruoho 18328c506b8Sjruoho /* Enter all elements into the namespace */ 18428c506b8Sjruoho 18528c506b8Sjruoho while (Child) 18628c506b8Sjruoho { 18728c506b8Sjruoho switch (Child->Asl.AmlOpcode) 18828c506b8Sjruoho { 18928c506b8Sjruoho case AML_INT_RESERVEDFIELD_OP: 19028c506b8Sjruoho case AML_INT_ACCESSFIELD_OP: 191ff4a156dSchristos case AML_INT_CONNECTION_OP: 19228c506b8Sjruoho break; 19328c506b8Sjruoho 19428c506b8Sjruoho default: 19528c506b8Sjruoho 19628c506b8Sjruoho Status = AcpiNsLookup (WalkState->ScopeInfo, 19728c506b8Sjruoho Child->Asl.Value.String, 19828c506b8Sjruoho ACPI_TYPE_LOCAL_REGION_FIELD, 19928c506b8Sjruoho ACPI_IMODE_LOAD_PASS1, 20028c506b8Sjruoho ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE | 20181bd9c9cSchristos ACPI_NS_ERROR_IF_FOUND, NULL, &Node); 20228c506b8Sjruoho if (ACPI_FAILURE (Status)) 20328c506b8Sjruoho { 20428c506b8Sjruoho if (Status != AE_ALREADY_EXISTS) 20528c506b8Sjruoho { 20628c506b8Sjruoho AslError (ASL_ERROR, ASL_MSG_CORE_EXCEPTION, Child, 20728c506b8Sjruoho Child->Asl.Value.String); 20828c506b8Sjruoho return (Status); 20928c506b8Sjruoho } 210ae01dbf5Schristos else if (Status == AE_ALREADY_EXISTS && 211ae01dbf5Schristos (Node->Flags & ANOBJ_IS_EXTERNAL) && 212ae01dbf5Schristos Node->OwnerId != WalkState->OwnerId) 213ae01dbf5Schristos { 214ae01dbf5Schristos Node->Type = (UINT8) ACPI_TYPE_LOCAL_REGION_FIELD; 215ae01dbf5Schristos } 216ae01dbf5Schristos else 217ae01dbf5Schristos { 21828c506b8Sjruoho /* 21928c506b8Sjruoho * The name already exists in this scope 22028c506b8Sjruoho * But continue processing the elements 22128c506b8Sjruoho */ 222*25666a51Schristos AslDualParseOpError (ASL_ERROR, ASL_MSG_NAME_EXISTS, Child, 223*25666a51Schristos Child->Asl.Value.String, ASL_MSG_FOUND_HERE, Node->Op, 224*25666a51Schristos Node->Op->Asl.ExternalName); 22528c506b8Sjruoho } 226ae01dbf5Schristos } 22728c506b8Sjruoho else 22828c506b8Sjruoho { 22928c506b8Sjruoho Child->Asl.Node = Node; 23028c506b8Sjruoho Node->Op = Child; 23128c506b8Sjruoho } 23228c506b8Sjruoho break; 23328c506b8Sjruoho } 234ff4a156dSchristos 23528c506b8Sjruoho Child = Child->Asl.Next; 23628c506b8Sjruoho } 237ff4a156dSchristos 23828c506b8Sjruoho return (AE_OK); 23928c506b8Sjruoho } 24028c506b8Sjruoho 24128c506b8Sjruoho 24228c506b8Sjruoho /******************************************************************************* 24328c506b8Sjruoho * 24428c506b8Sjruoho * FUNCTION: LdLoadResourceElements 24528c506b8Sjruoho * 24628c506b8Sjruoho * PARAMETERS: Op - Parent node (Resource Descriptor) 24728c506b8Sjruoho * WalkState - Current walk state 24828c506b8Sjruoho * 24928c506b8Sjruoho * RETURN: Status 25028c506b8Sjruoho * 25128c506b8Sjruoho * DESCRIPTION: Enter the named elements of the resource descriptor (children 25228c506b8Sjruoho * of the parent) into the namespace. 25328c506b8Sjruoho * 25428c506b8Sjruoho * NOTE: In the real AML namespace, these named elements never exist. But 25528c506b8Sjruoho * we simply use the namespace here as a symbol table so we can look 25628c506b8Sjruoho * them up as they are referenced. 25728c506b8Sjruoho * 25828c506b8Sjruoho ******************************************************************************/ 25928c506b8Sjruoho 26028c506b8Sjruoho static ACPI_STATUS 26128c506b8Sjruoho LdLoadResourceElements ( 26228c506b8Sjruoho ACPI_PARSE_OBJECT *Op, 26328c506b8Sjruoho ACPI_WALK_STATE *WalkState) 26428c506b8Sjruoho { 26528c506b8Sjruoho ACPI_PARSE_OBJECT *InitializerOp = NULL; 26628c506b8Sjruoho ACPI_NAMESPACE_NODE *Node; 26728c506b8Sjruoho ACPI_STATUS Status; 26828c506b8Sjruoho 26928c506b8Sjruoho 27028c506b8Sjruoho /* 27128c506b8Sjruoho * Enter the resource name into the namespace. Name must not already exist. 27228c506b8Sjruoho * This opens a scope, so later field names are guaranteed to be new/unique. 27328c506b8Sjruoho */ 27428c506b8Sjruoho Status = AcpiNsLookup (WalkState->ScopeInfo, Op->Asl.Namepath, 27528c506b8Sjruoho ACPI_TYPE_LOCAL_RESOURCE, ACPI_IMODE_LOAD_PASS1, 27628c506b8Sjruoho ACPI_NS_NO_UPSEARCH | ACPI_NS_ERROR_IF_FOUND, 27728c506b8Sjruoho WalkState, &Node); 27828c506b8Sjruoho if (ACPI_FAILURE (Status)) 27928c506b8Sjruoho { 28028c506b8Sjruoho if (Status == AE_ALREADY_EXISTS) 28128c506b8Sjruoho { 28228c506b8Sjruoho /* Actual node causing the error was saved in ParentMethod */ 28328c506b8Sjruoho 284*25666a51Schristos AslDualParseOpError (ASL_ERROR, ASL_MSG_NAME_EXISTS, 285*25666a51Schristos (ACPI_PARSE_OBJECT *) Op->Asl.ParentMethod, 286*25666a51Schristos Op->Asl.Namepath, ASL_MSG_FOUND_HERE, Node->Op, 287*25666a51Schristos Node->Op->Asl.ExternalName); 28828c506b8Sjruoho return (AE_OK); 28928c506b8Sjruoho } 29028c506b8Sjruoho return (Status); 29128c506b8Sjruoho } 29228c506b8Sjruoho 29328c506b8Sjruoho Node->Value = (UINT32) Op->Asl.Value.Integer; 29428c506b8Sjruoho Node->Op = Op; 29528c506b8Sjruoho Op->Asl.Node = Node; 29628c506b8Sjruoho 29728c506b8Sjruoho /* 29828c506b8Sjruoho * Now enter the predefined fields, for easy lookup when referenced 29928c506b8Sjruoho * by the source ASL 30028c506b8Sjruoho */ 30128c506b8Sjruoho InitializerOp = ASL_GET_CHILD_NODE (Op); 30228c506b8Sjruoho while (InitializerOp) 30328c506b8Sjruoho { 30428c506b8Sjruoho if (InitializerOp->Asl.ExternalName) 30528c506b8Sjruoho { 30628c506b8Sjruoho Status = AcpiNsLookup (WalkState->ScopeInfo, 30728c506b8Sjruoho InitializerOp->Asl.ExternalName, 30828c506b8Sjruoho ACPI_TYPE_LOCAL_RESOURCE_FIELD, 30928c506b8Sjruoho ACPI_IMODE_LOAD_PASS1, 31028c506b8Sjruoho ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE, 31128c506b8Sjruoho NULL, &Node); 31228c506b8Sjruoho if (ACPI_FAILURE (Status)) 31328c506b8Sjruoho { 31428c506b8Sjruoho return (Status); 31528c506b8Sjruoho } 31628c506b8Sjruoho 31728c506b8Sjruoho /* 318ff4a156dSchristos * Store the field offset and length in the namespace node 319ff4a156dSchristos * so it can be used when the field is referenced 32028c506b8Sjruoho */ 321ff4a156dSchristos Node->Value = InitializerOp->Asl.Value.Tag.BitOffset; 322ff4a156dSchristos Node->Length = InitializerOp->Asl.Value.Tag.BitLength; 32328c506b8Sjruoho InitializerOp->Asl.Node = Node; 32428c506b8Sjruoho Node->Op = InitializerOp; 32528c506b8Sjruoho } 326ff4a156dSchristos 32728c506b8Sjruoho InitializerOp = ASL_GET_PEER_NODE (InitializerOp); 32828c506b8Sjruoho } 32928c506b8Sjruoho 33028c506b8Sjruoho return (AE_OK); 33128c506b8Sjruoho } 33228c506b8Sjruoho 33328c506b8Sjruoho 33428c506b8Sjruoho /******************************************************************************* 33528c506b8Sjruoho * 33628c506b8Sjruoho * FUNCTION: LdNamespace1Begin 33728c506b8Sjruoho * 33828c506b8Sjruoho * PARAMETERS: ASL_WALK_CALLBACK 33928c506b8Sjruoho * 34028c506b8Sjruoho * RETURN: Status 34128c506b8Sjruoho * 34228c506b8Sjruoho * DESCRIPTION: Descending callback used during the parse tree walk. If this 34328c506b8Sjruoho * is a named AML opcode, enter into the namespace 34428c506b8Sjruoho * 34528c506b8Sjruoho ******************************************************************************/ 34628c506b8Sjruoho 34728c506b8Sjruoho static ACPI_STATUS 34828c506b8Sjruoho LdNamespace1Begin ( 34928c506b8Sjruoho ACPI_PARSE_OBJECT *Op, 35028c506b8Sjruoho UINT32 Level, 35128c506b8Sjruoho void *Context) 35228c506b8Sjruoho { 35328c506b8Sjruoho ACPI_WALK_STATE *WalkState = (ACPI_WALK_STATE *) Context; 35428c506b8Sjruoho ACPI_NAMESPACE_NODE *Node; 35581bd9c9cSchristos ACPI_PARSE_OBJECT *MethodOp; 35628c506b8Sjruoho ACPI_STATUS Status; 35728c506b8Sjruoho ACPI_OBJECT_TYPE ObjectType; 35828c506b8Sjruoho ACPI_OBJECT_TYPE ActualObjectType = ACPI_TYPE_ANY; 35928c506b8Sjruoho char *Path; 36028c506b8Sjruoho UINT32 Flags = ACPI_NS_NO_UPSEARCH; 36128c506b8Sjruoho ACPI_PARSE_OBJECT *Arg; 36228c506b8Sjruoho UINT32 i; 36328c506b8Sjruoho BOOLEAN ForceNewScope = FALSE; 364ae01dbf5Schristos ACPI_OWNER_ID OwnerId = 0; 36528c506b8Sjruoho 36628c506b8Sjruoho 36728c506b8Sjruoho ACPI_FUNCTION_NAME (LdNamespace1Begin); 36828c506b8Sjruoho ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Op %p [%s]\n", 36928c506b8Sjruoho Op, Op->Asl.ParseOpName)); 37028c506b8Sjruoho 371ae01dbf5Schristos if (Op->Asl.ParseOpcode == PARSEOP_DEFINITION_BLOCK) 372ae01dbf5Schristos { 373ae01dbf5Schristos /* 374ae01dbf5Schristos * Allocate an OwnerId for this block. This helps identify the owners 375ae01dbf5Schristos * of each namespace node. This is used in determining whether if 376ae01dbf5Schristos * certain external declarations cause redefinition errors. 377ae01dbf5Schristos */ 378ae01dbf5Schristos Status = AcpiUtAllocateOwnerId (&OwnerId); 379ae01dbf5Schristos WalkState->OwnerId = OwnerId; 380ae01dbf5Schristos if (ACPI_FAILURE (Status)) 381ae01dbf5Schristos { 382ae01dbf5Schristos AslCoreSubsystemError (Op, Status, 383ae01dbf5Schristos "Failure to allocate owner ID to this definition block.", FALSE); 384ae01dbf5Schristos return_ACPI_STATUS (Status); 385ae01dbf5Schristos } 386ae01dbf5Schristos } 387ae01dbf5Schristos 38828c506b8Sjruoho /* 38928c506b8Sjruoho * We are only interested in opcodes that have an associated name 39028c506b8Sjruoho * (or multiple names) 39128c506b8Sjruoho */ 39228c506b8Sjruoho switch (Op->Asl.AmlOpcode) 39328c506b8Sjruoho { 39428c506b8Sjruoho case AML_BANK_FIELD_OP: 39528c506b8Sjruoho case AML_INDEX_FIELD_OP: 39628c506b8Sjruoho case AML_FIELD_OP: 39728c506b8Sjruoho 39828c506b8Sjruoho Status = LdLoadFieldElements (Op, WalkState); 39928c506b8Sjruoho return (Status); 40028c506b8Sjruoho 401414ef032Schristos case AML_INT_CONNECTION_OP: 402414ef032Schristos 403414ef032Schristos 404414ef032Schristos if (Op->Asl.Child->Asl.AmlOpcode != AML_INT_NAMEPATH_OP) 405414ef032Schristos { 406414ef032Schristos break; 407414ef032Schristos } 408414ef032Schristos Arg = Op->Asl.Child; 409414ef032Schristos 410414ef032Schristos Status = AcpiNsLookup (WalkState->ScopeInfo, Arg->Asl.ExternalName, 411414ef032Schristos ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT, 412414ef032Schristos WalkState, &Node); 413414ef032Schristos if (ACPI_FAILURE (Status)) 414414ef032Schristos { 415414ef032Schristos break; 416414ef032Schristos } 417414ef032Schristos 418414ef032Schristos if (Node->Type == ACPI_TYPE_BUFFER) 419414ef032Schristos { 420414ef032Schristos Arg->Asl.Node = Node; 421414ef032Schristos 422414ef032Schristos Arg = Node->Op->Asl.Child; /* Get namepath */ 423414ef032Schristos Arg = Arg->Asl.Next; /* Get actual buffer */ 424414ef032Schristos Arg = Arg->Asl.Child; /* Buffer length */ 425414ef032Schristos Arg = Arg->Asl.Next; /* RAW_DATA buffer */ 426414ef032Schristos } 427414ef032Schristos break; 428414ef032Schristos 42928c506b8Sjruoho default: 43028c506b8Sjruoho 43128c506b8Sjruoho /* All other opcodes go below */ 432ff4a156dSchristos 43328c506b8Sjruoho break; 43428c506b8Sjruoho } 43528c506b8Sjruoho 43628c506b8Sjruoho /* Check if this object has already been installed in the namespace */ 43728c506b8Sjruoho 43828c506b8Sjruoho if (Op->Asl.Node) 43928c506b8Sjruoho { 44028c506b8Sjruoho return (AE_OK); 44128c506b8Sjruoho } 44228c506b8Sjruoho 44328c506b8Sjruoho Path = Op->Asl.Namepath; 44428c506b8Sjruoho if (!Path) 44528c506b8Sjruoho { 44628c506b8Sjruoho return (AE_OK); 44728c506b8Sjruoho } 44828c506b8Sjruoho 44928c506b8Sjruoho /* Map the raw opcode into an internal object type */ 45028c506b8Sjruoho 45128c506b8Sjruoho switch (Op->Asl.ParseOpcode) 45228c506b8Sjruoho { 45328c506b8Sjruoho case PARSEOP_NAME: 45428c506b8Sjruoho 45528c506b8Sjruoho Arg = Op->Asl.Child; /* Get the NameSeg/NameString node */ 45628c506b8Sjruoho Arg = Arg->Asl.Next; /* First peer is the object to be associated with the name */ 45728c506b8Sjruoho 45828c506b8Sjruoho /* 45928c506b8Sjruoho * If this name refers to a ResourceTemplate, we will need to open 46028c506b8Sjruoho * a new scope so that the resource subfield names can be entered into 46128c506b8Sjruoho * the namespace underneath this name 46228c506b8Sjruoho */ 463ae01dbf5Schristos if (Op->Asl.CompileFlags & OP_IS_RESOURCE_DESC) 46428c506b8Sjruoho { 46528c506b8Sjruoho ForceNewScope = TRUE; 46628c506b8Sjruoho } 46728c506b8Sjruoho 46828c506b8Sjruoho /* Get the data type associated with the named object, not the name itself */ 46928c506b8Sjruoho 47028c506b8Sjruoho /* Log2 loop to convert from Btype (binary) to Etype (encoded) */ 47128c506b8Sjruoho 47228c506b8Sjruoho ObjectType = 1; 47328c506b8Sjruoho for (i = 1; i < Arg->Asl.AcpiBtype; i *= 2) 47428c506b8Sjruoho { 47528c506b8Sjruoho ObjectType++; 47628c506b8Sjruoho } 47728c506b8Sjruoho break; 47828c506b8Sjruoho 47928c506b8Sjruoho 48028c506b8Sjruoho case PARSEOP_EXTERNAL: 48128c506b8Sjruoho /* 48228c506b8Sjruoho * "External" simply enters a name and type into the namespace. 48328c506b8Sjruoho * We must be careful to not open a new scope, however, no matter 48428c506b8Sjruoho * what type the external name refers to (e.g., a method) 48528c506b8Sjruoho * 48628c506b8Sjruoho * first child is name, next child is ObjectType 48728c506b8Sjruoho */ 48828c506b8Sjruoho ActualObjectType = (UINT8) Op->Asl.Child->Asl.Next->Asl.Value.Integer; 48928c506b8Sjruoho ObjectType = ACPI_TYPE_ANY; 49028c506b8Sjruoho 49128c506b8Sjruoho /* 49228c506b8Sjruoho * We will mark every new node along the path as "External". This 49328c506b8Sjruoho * allows some or all of the nodes to be created later in the ASL 49428c506b8Sjruoho * code. Handles cases like this: 49528c506b8Sjruoho * 49628c506b8Sjruoho * External (\_SB_.PCI0.ABCD, IntObj) 49728c506b8Sjruoho * Scope (_SB_) 49828c506b8Sjruoho * { 49928c506b8Sjruoho * Device (PCI0) 50028c506b8Sjruoho * { 50128c506b8Sjruoho * } 50228c506b8Sjruoho * } 50328c506b8Sjruoho * Method (X) 50428c506b8Sjruoho * { 50528c506b8Sjruoho * Store (\_SB_.PCI0.ABCD, Local0) 50628c506b8Sjruoho * } 50728c506b8Sjruoho */ 50828c506b8Sjruoho Flags |= ACPI_NS_EXTERNAL; 50928c506b8Sjruoho break; 51028c506b8Sjruoho 51128c506b8Sjruoho case PARSEOP_DEFAULT_ARG: 51228c506b8Sjruoho 513ae01dbf5Schristos if (Op->Asl.CompileFlags == OP_IS_RESOURCE_DESC) 51428c506b8Sjruoho { 51528c506b8Sjruoho Status = LdLoadResourceElements (Op, WalkState); 51628c506b8Sjruoho return_ACPI_STATUS (Status); 51728c506b8Sjruoho } 51828c506b8Sjruoho 51928c506b8Sjruoho ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode); 52028c506b8Sjruoho break; 52128c506b8Sjruoho 52228c506b8Sjruoho case PARSEOP_SCOPE: 52328c506b8Sjruoho /* 52428c506b8Sjruoho * The name referenced by Scope(Name) must already exist at this point. 52528c506b8Sjruoho * In other words, forward references for Scope() are not supported. 52628c506b8Sjruoho * The only real reason for this is that the MS interpreter cannot 52728c506b8Sjruoho * handle this case. Perhaps someday this case can go away. 52828c506b8Sjruoho */ 52928c506b8Sjruoho Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ACPI_TYPE_ANY, 53028c506b8Sjruoho ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT, 53128c506b8Sjruoho WalkState, &(Node)); 53228c506b8Sjruoho if (ACPI_FAILURE (Status)) 53328c506b8Sjruoho { 53428c506b8Sjruoho if (Status == AE_NOT_FOUND) 53528c506b8Sjruoho { 53628c506b8Sjruoho /* The name was not found, go ahead and create it */ 53728c506b8Sjruoho 53828c506b8Sjruoho Status = AcpiNsLookup (WalkState->ScopeInfo, Path, 53928c506b8Sjruoho ACPI_TYPE_LOCAL_SCOPE, 54028c506b8Sjruoho ACPI_IMODE_LOAD_PASS1, Flags, 54128c506b8Sjruoho WalkState, &(Node)); 542ff4a156dSchristos if (ACPI_FAILURE (Status)) 543ff4a156dSchristos { 544ff4a156dSchristos return_ACPI_STATUS (Status); 545ff4a156dSchristos } 54628c506b8Sjruoho 54728c506b8Sjruoho /* 54828c506b8Sjruoho * However, this is an error -- primarily because the MS 54928c506b8Sjruoho * interpreter can't handle a forward reference from the 55028c506b8Sjruoho * Scope() operator. 55128c506b8Sjruoho */ 55228c506b8Sjruoho AslError (ASL_ERROR, ASL_MSG_NOT_FOUND, Op, 55328c506b8Sjruoho Op->Asl.ExternalName); 55428c506b8Sjruoho AslError (ASL_ERROR, ASL_MSG_SCOPE_FWD_REF, Op, 55528c506b8Sjruoho Op->Asl.ExternalName); 55628c506b8Sjruoho goto FinishNode; 55728c506b8Sjruoho } 55828c506b8Sjruoho 55928c506b8Sjruoho AslCoreSubsystemError (Op, Status, 56028c506b8Sjruoho "Failure from namespace lookup", FALSE); 56128c506b8Sjruoho 56228c506b8Sjruoho return_ACPI_STATUS (Status); 56328c506b8Sjruoho } 56481bd9c9cSchristos else /* Status AE_OK */ 56581bd9c9cSchristos { 56681bd9c9cSchristos /* 56781bd9c9cSchristos * Do not allow references to external scopes from the DSDT. 56881bd9c9cSchristos * This is because the DSDT is always loaded first, and the 56981bd9c9cSchristos * external reference cannot be resolved -- causing a runtime 57081bd9c9cSchristos * error because Scope() must be resolved immediately. 57181bd9c9cSchristos * 10/2015. 57281bd9c9cSchristos */ 57381bd9c9cSchristos if ((Node->Flags & ANOBJ_IS_EXTERNAL) && 57481bd9c9cSchristos (ACPI_COMPARE_NAME (Gbl_TableSignature, "DSDT"))) 57581bd9c9cSchristos { 57681bd9c9cSchristos /* However, allowed if the reference is within a method */ 57781bd9c9cSchristos 57881bd9c9cSchristos MethodOp = Op->Asl.Parent; 57981bd9c9cSchristos while (MethodOp && 58081bd9c9cSchristos (MethodOp->Asl.ParseOpcode != PARSEOP_METHOD)) 58181bd9c9cSchristos { 58281bd9c9cSchristos MethodOp = MethodOp->Asl.Parent; 58381bd9c9cSchristos } 58481bd9c9cSchristos 58581bd9c9cSchristos if (!MethodOp) 58681bd9c9cSchristos { 58781bd9c9cSchristos /* Not in a control method, error */ 58881bd9c9cSchristos 58981bd9c9cSchristos AslError (ASL_ERROR, ASL_MSG_CROSS_TABLE_SCOPE, Op, NULL); 59081bd9c9cSchristos } 59181bd9c9cSchristos } 59281bd9c9cSchristos } 59328c506b8Sjruoho 59428c506b8Sjruoho /* We found a node with this name, now check the type */ 59528c506b8Sjruoho 59628c506b8Sjruoho switch (Node->Type) 59728c506b8Sjruoho { 59828c506b8Sjruoho case ACPI_TYPE_LOCAL_SCOPE: 59928c506b8Sjruoho case ACPI_TYPE_DEVICE: 60028c506b8Sjruoho case ACPI_TYPE_POWER: 60128c506b8Sjruoho case ACPI_TYPE_PROCESSOR: 60228c506b8Sjruoho case ACPI_TYPE_THERMAL: 60328c506b8Sjruoho 60428c506b8Sjruoho /* These are acceptable types - they all open a new scope */ 60528c506b8Sjruoho break; 60628c506b8Sjruoho 60728c506b8Sjruoho case ACPI_TYPE_INTEGER: 60828c506b8Sjruoho case ACPI_TYPE_STRING: 60928c506b8Sjruoho case ACPI_TYPE_BUFFER: 61028c506b8Sjruoho /* 61128c506b8Sjruoho * These types we will allow, but we will change the type. 61228c506b8Sjruoho * This enables some existing code of the form: 61328c506b8Sjruoho * 61428c506b8Sjruoho * Name (DEB, 0) 61528c506b8Sjruoho * Scope (DEB) { ... } 61628c506b8Sjruoho * 61728c506b8Sjruoho * Which is used to workaround the fact that the MS interpreter 61828c506b8Sjruoho * does not allow Scope() forward references. 61928c506b8Sjruoho */ 62052afc2f5Schristos snprintf (MsgBuffer, sizeof(MsgBuffer), "%s [%s], changing type to [Scope]", 62128c506b8Sjruoho Op->Asl.ExternalName, AcpiUtGetTypeName (Node->Type)); 62228c506b8Sjruoho AslError (ASL_REMARK, ASL_MSG_SCOPE_TYPE, Op, MsgBuffer); 62328c506b8Sjruoho 62428c506b8Sjruoho /* Switch the type to scope, open the new scope */ 62528c506b8Sjruoho 62628c506b8Sjruoho Node->Type = ACPI_TYPE_LOCAL_SCOPE; 62728c506b8Sjruoho Status = AcpiDsScopeStackPush (Node, ACPI_TYPE_LOCAL_SCOPE, 62828c506b8Sjruoho WalkState); 62928c506b8Sjruoho if (ACPI_FAILURE (Status)) 63028c506b8Sjruoho { 63128c506b8Sjruoho return_ACPI_STATUS (Status); 63228c506b8Sjruoho } 63328c506b8Sjruoho break; 63428c506b8Sjruoho 63528c506b8Sjruoho default: 63628c506b8Sjruoho 63728c506b8Sjruoho /* All other types are an error */ 63828c506b8Sjruoho 63952afc2f5Schristos snprintf (MsgBuffer, sizeof(MsgBuffer), "%s [%s]", Op->Asl.ExternalName, 64028c506b8Sjruoho AcpiUtGetTypeName (Node->Type)); 64128c506b8Sjruoho AslError (ASL_ERROR, ASL_MSG_SCOPE_TYPE, Op, MsgBuffer); 64228c506b8Sjruoho 64328c506b8Sjruoho /* 64428c506b8Sjruoho * However, switch the type to be an actual scope so 64528c506b8Sjruoho * that compilation can continue without generating a whole 64628c506b8Sjruoho * cascade of additional errors. Open the new scope. 64728c506b8Sjruoho */ 64828c506b8Sjruoho Node->Type = ACPI_TYPE_LOCAL_SCOPE; 64928c506b8Sjruoho Status = AcpiDsScopeStackPush (Node, ACPI_TYPE_LOCAL_SCOPE, 65028c506b8Sjruoho WalkState); 65128c506b8Sjruoho if (ACPI_FAILURE (Status)) 65228c506b8Sjruoho { 65328c506b8Sjruoho return_ACPI_STATUS (Status); 65428c506b8Sjruoho } 65528c506b8Sjruoho break; 65628c506b8Sjruoho } 65728c506b8Sjruoho 65828c506b8Sjruoho Status = AE_OK; 65928c506b8Sjruoho goto FinishNode; 66028c506b8Sjruoho 66128c506b8Sjruoho 66228c506b8Sjruoho default: 66328c506b8Sjruoho 66428c506b8Sjruoho ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode); 66528c506b8Sjruoho break; 66628c506b8Sjruoho } 66728c506b8Sjruoho 66828c506b8Sjruoho 66928c506b8Sjruoho ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Loading name: %s, (%s)\n", 67028c506b8Sjruoho Op->Asl.ExternalName, AcpiUtGetTypeName (ObjectType))); 67128c506b8Sjruoho 67228c506b8Sjruoho /* The name must not already exist */ 67328c506b8Sjruoho 67428c506b8Sjruoho Flags |= ACPI_NS_ERROR_IF_FOUND; 67528c506b8Sjruoho 67628c506b8Sjruoho /* 67728c506b8Sjruoho * Enter the named type into the internal namespace. We enter the name 67828c506b8Sjruoho * as we go downward in the parse tree. Any necessary subobjects that 67928c506b8Sjruoho * involve arguments to the opcode must be created as we go back up the 68028c506b8Sjruoho * parse tree later. 68128c506b8Sjruoho */ 68228c506b8Sjruoho Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ObjectType, 68328c506b8Sjruoho ACPI_IMODE_LOAD_PASS1, Flags, WalkState, &Node); 68428c506b8Sjruoho if (ACPI_FAILURE (Status)) 68528c506b8Sjruoho { 68628c506b8Sjruoho if (Status == AE_ALREADY_EXISTS) 68728c506b8Sjruoho { 68828c506b8Sjruoho /* The name already exists in this scope */ 68928c506b8Sjruoho 69028c506b8Sjruoho if (Node->Type == ACPI_TYPE_LOCAL_SCOPE) 69128c506b8Sjruoho { 69228c506b8Sjruoho /* Allow multiple references to the same scope */ 69328c506b8Sjruoho 69428c506b8Sjruoho Node->Type = (UINT8) ObjectType; 69528c506b8Sjruoho Status = AE_OK; 69628c506b8Sjruoho } 69728c506b8Sjruoho else if ((Node->Flags & ANOBJ_IS_EXTERNAL) && 69828c506b8Sjruoho (Op->Asl.ParseOpcode != PARSEOP_EXTERNAL)) 69928c506b8Sjruoho { 70028c506b8Sjruoho /* 70128c506b8Sjruoho * Allow one create on an object or segment that was 702ae01dbf5Schristos * previously declared External only if WalkState->OwnerId and 703*25666a51Schristos * Node->OwnerId are different (meaning that the current WalkState 704*25666a51Schristos * and the Node are in different tables). 70528c506b8Sjruoho */ 70628c506b8Sjruoho Node->Flags &= ~ANOBJ_IS_EXTERNAL; 70728c506b8Sjruoho Node->Type = (UINT8) ObjectType; 70828c506b8Sjruoho 70928c506b8Sjruoho /* Just retyped a node, probably will need to open a scope */ 71028c506b8Sjruoho 71128c506b8Sjruoho if (AcpiNsOpensScope (ObjectType)) 71228c506b8Sjruoho { 71328c506b8Sjruoho Status = AcpiDsScopeStackPush (Node, ObjectType, WalkState); 71428c506b8Sjruoho if (ACPI_FAILURE (Status)) 71528c506b8Sjruoho { 71628c506b8Sjruoho return_ACPI_STATUS (Status); 71728c506b8Sjruoho } 71828c506b8Sjruoho } 71981bd9c9cSchristos 72081bd9c9cSchristos Status = AE_OK; 721ae01dbf5Schristos 722ae01dbf5Schristos if (Node->OwnerId == WalkState->OwnerId && 723ae01dbf5Schristos !(Node->Flags & IMPLICIT_EXTERNAL)) 724ae01dbf5Schristos { 725*25666a51Schristos AslDualParseOpError (ASL_ERROR, ASL_MSG_NAME_EXISTS, Op, 726*25666a51Schristos Op->Asl.ExternalName, ASL_MSG_FOUND_HERE, Node->Op, 727*25666a51Schristos Node->Op->Asl.ExternalName); 728ae01dbf5Schristos } 729ae01dbf5Schristos if (Node->Flags & IMPLICIT_EXTERNAL) 730ae01dbf5Schristos { 731ae01dbf5Schristos Node->Flags &= ~IMPLICIT_EXTERNAL; 732ae01dbf5Schristos } 73381bd9c9cSchristos } 73481bd9c9cSchristos else if (!(Node->Flags & ANOBJ_IS_EXTERNAL) && 73581bd9c9cSchristos (Op->Asl.ParseOpcode == PARSEOP_EXTERNAL)) 73681bd9c9cSchristos { 73781bd9c9cSchristos /* 73881bd9c9cSchristos * Allow externals in same scope as the definition of the 73981bd9c9cSchristos * actual object. Similar to C. Allows multiple definition 740ae01dbf5Schristos * blocks that refer to each other in the same file. However, 741ae01dbf5Schristos * do not allow name declaration and an external declaration 742ae01dbf5Schristos * within the same table. This is considered a re-declaration. 74381bd9c9cSchristos */ 74428c506b8Sjruoho Status = AE_OK; 745ae01dbf5Schristos 746ae01dbf5Schristos if (Node->OwnerId == WalkState->OwnerId) 747ae01dbf5Schristos { 748*25666a51Schristos AslDualParseOpError (ASL_ERROR, ASL_MSG_NAME_EXISTS, Op, 749*25666a51Schristos Op->Asl.ExternalName, ASL_MSG_FOUND_HERE, Node->Op, 750*25666a51Schristos Node->Op->Asl.ExternalName); 751ae01dbf5Schristos } 75228c506b8Sjruoho } 75349c2f1f4Schristos else if ((Node->Flags & ANOBJ_IS_EXTERNAL) && 75449c2f1f4Schristos (Op->Asl.ParseOpcode == PARSEOP_EXTERNAL) && 75549c2f1f4Schristos (ObjectType == ACPI_TYPE_ANY)) 75649c2f1f4Schristos { 757ae01dbf5Schristos /* 758ae01dbf5Schristos * Allow update of externals of unknown type. 759ae01dbf5Schristos * In the case that multiple definition blocks are being 760ae01dbf5Schristos * parsed, updating the OwnerId allows enables subsequent calls 761ae01dbf5Schristos * of this method to understand which table the most recent 762ae01dbf5Schristos * external declaration was seen. Without this OwnerId update, 763ae01dbf5Schristos * code like the following is allowed to compile: 764ae01dbf5Schristos * 765ae01dbf5Schristos * DefinitionBlock("externtest.aml", "DSDT", 0x02, "Intel", "Many", 0x00000001) 766ae01dbf5Schristos * { 767ae01dbf5Schristos * External(ERRS,methodobj) 768ae01dbf5Schristos * Method (MAIN) 769ae01dbf5Schristos * { 770ae01dbf5Schristos * Name(NUM2, 0) 771ae01dbf5Schristos * ERRS(1,2,3) 772ae01dbf5Schristos * } 773ae01dbf5Schristos * } 774ae01dbf5Schristos * 775ae01dbf5Schristos * DefinitionBlock("externtest.aml", "SSDT", 0x02, "Intel", "Many", 0x00000001) 776ae01dbf5Schristos * { 777ae01dbf5Schristos * if (0) 778ae01dbf5Schristos * { 779ae01dbf5Schristos * External(ERRS,methodobj) 780ae01dbf5Schristos * } 781ae01dbf5Schristos * Method (ERRS,3) 782ae01dbf5Schristos * {} 783ae01dbf5Schristos * 784ae01dbf5Schristos * } 785ae01dbf5Schristos */ 786ae01dbf5Schristos Node->OwnerId = WalkState->OwnerId; 78749c2f1f4Schristos 78849c2f1f4Schristos if (AcpiNsOpensScope (ActualObjectType)) 78949c2f1f4Schristos { 79049c2f1f4Schristos Node->Type = (UINT8) ActualObjectType; 79149c2f1f4Schristos Status = AE_OK; 79249c2f1f4Schristos } 79349c2f1f4Schristos else 79449c2f1f4Schristos { 79549c2f1f4Schristos sprintf (MsgBuffer, "%s [%s]", Op->Asl.ExternalName, 79649c2f1f4Schristos AcpiUtGetTypeName (Node->Type)); 79749c2f1f4Schristos AslError (ASL_ERROR, ASL_MSG_SCOPE_TYPE, Op, MsgBuffer); 79849c2f1f4Schristos return_ACPI_STATUS (AE_OK); 79949c2f1f4Schristos } 80049c2f1f4Schristos } 80128c506b8Sjruoho else 80228c506b8Sjruoho { 80328c506b8Sjruoho /* Valid error, object already exists */ 80428c506b8Sjruoho 805*25666a51Schristos AslDualParseOpError (ASL_ERROR, ASL_MSG_NAME_EXISTS, Op, 806*25666a51Schristos Op->Asl.ExternalName, ASL_MSG_FOUND_HERE, Node->Op, 807*25666a51Schristos Node->Op->Asl.ExternalName); 80828c506b8Sjruoho return_ACPI_STATUS (AE_OK); 80928c506b8Sjruoho } 81028c506b8Sjruoho } 81128c506b8Sjruoho else 81228c506b8Sjruoho { 81328c506b8Sjruoho AslCoreSubsystemError (Op, Status, 81428c506b8Sjruoho "Failure from namespace lookup", FALSE); 81528c506b8Sjruoho return_ACPI_STATUS (Status); 81628c506b8Sjruoho } 81728c506b8Sjruoho } 81828c506b8Sjruoho 81928c506b8Sjruoho if (ForceNewScope) 82028c506b8Sjruoho { 82128c506b8Sjruoho Status = AcpiDsScopeStackPush (Node, ObjectType, WalkState); 82228c506b8Sjruoho if (ACPI_FAILURE (Status)) 82328c506b8Sjruoho { 82428c506b8Sjruoho return_ACPI_STATUS (Status); 82528c506b8Sjruoho } 82628c506b8Sjruoho } 82728c506b8Sjruoho 82828c506b8Sjruoho FinishNode: 82928c506b8Sjruoho /* 83028c506b8Sjruoho * Point the parse node to the new namespace node, and point 83128c506b8Sjruoho * the Node back to the original Parse node 83228c506b8Sjruoho */ 83328c506b8Sjruoho Op->Asl.Node = Node; 83428c506b8Sjruoho Node->Op = Op; 83528c506b8Sjruoho 83628c506b8Sjruoho /* Set the actual data type if appropriate (EXTERNAL term only) */ 83728c506b8Sjruoho 83828c506b8Sjruoho if (ActualObjectType != ACPI_TYPE_ANY) 83928c506b8Sjruoho { 84028c506b8Sjruoho Node->Type = (UINT8) ActualObjectType; 84128c506b8Sjruoho Node->Value = ASL_EXTERNAL_METHOD; 84228c506b8Sjruoho } 84328c506b8Sjruoho 84428c506b8Sjruoho if (Op->Asl.ParseOpcode == PARSEOP_METHOD) 84528c506b8Sjruoho { 84628c506b8Sjruoho /* 84728c506b8Sjruoho * Get the method argument count from "Extra" and save 84828c506b8Sjruoho * it in the namespace node 84928c506b8Sjruoho */ 85028c506b8Sjruoho Node->Value = (UINT32) Op->Asl.Extra; 85128c506b8Sjruoho } 85228c506b8Sjruoho 85328c506b8Sjruoho return_ACPI_STATUS (Status); 85428c506b8Sjruoho } 85528c506b8Sjruoho 85628c506b8Sjruoho 85728c506b8Sjruoho /******************************************************************************* 85828c506b8Sjruoho * 85928c506b8Sjruoho * FUNCTION: LdNamespace2Begin 86028c506b8Sjruoho * 86128c506b8Sjruoho * PARAMETERS: ASL_WALK_CALLBACK 86228c506b8Sjruoho * 86328c506b8Sjruoho * RETURN: Status 86428c506b8Sjruoho * 86528c506b8Sjruoho * DESCRIPTION: Descending callback used during the pass 2 parse tree walk. 86628c506b8Sjruoho * Second pass resolves some forward references. 86728c506b8Sjruoho * 86828c506b8Sjruoho * Notes: 86928c506b8Sjruoho * Currently only needs to handle the Alias operator. 87028c506b8Sjruoho * Could be used to allow forward references from the Scope() operator, but 87128c506b8Sjruoho * the MS interpreter does not allow this, so this compiler does not either. 87228c506b8Sjruoho * 87328c506b8Sjruoho ******************************************************************************/ 87428c506b8Sjruoho 87528c506b8Sjruoho static ACPI_STATUS 87628c506b8Sjruoho LdNamespace2Begin ( 87728c506b8Sjruoho ACPI_PARSE_OBJECT *Op, 87828c506b8Sjruoho UINT32 Level, 87928c506b8Sjruoho void *Context) 88028c506b8Sjruoho { 88128c506b8Sjruoho ACPI_WALK_STATE *WalkState = (ACPI_WALK_STATE *) Context; 88228c506b8Sjruoho ACPI_STATUS Status; 88328c506b8Sjruoho ACPI_NAMESPACE_NODE *Node; 88428c506b8Sjruoho ACPI_OBJECT_TYPE ObjectType; 88528c506b8Sjruoho BOOLEAN ForceNewScope = FALSE; 88628c506b8Sjruoho ACPI_PARSE_OBJECT *Arg; 88728c506b8Sjruoho char *Path; 88828c506b8Sjruoho ACPI_NAMESPACE_NODE *TargetNode; 88928c506b8Sjruoho 89028c506b8Sjruoho 89128c506b8Sjruoho ACPI_FUNCTION_NAME (LdNamespace2Begin); 89228c506b8Sjruoho ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Op %p [%s]\n", 89328c506b8Sjruoho Op, Op->Asl.ParseOpName)); 89428c506b8Sjruoho 89528c506b8Sjruoho 89628c506b8Sjruoho /* Ignore Ops with no namespace node */ 89728c506b8Sjruoho 89828c506b8Sjruoho Node = Op->Asl.Node; 89928c506b8Sjruoho if (!Node) 90028c506b8Sjruoho { 90128c506b8Sjruoho return (AE_OK); 90228c506b8Sjruoho } 90328c506b8Sjruoho 90428c506b8Sjruoho /* Get the type to determine if we should push the scope */ 90528c506b8Sjruoho 90628c506b8Sjruoho if ((Op->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG) && 907ae01dbf5Schristos (Op->Asl.CompileFlags == OP_IS_RESOURCE_DESC)) 90828c506b8Sjruoho { 90928c506b8Sjruoho ObjectType = ACPI_TYPE_LOCAL_RESOURCE; 91028c506b8Sjruoho } 91128c506b8Sjruoho else 91228c506b8Sjruoho { 91328c506b8Sjruoho ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode); 91428c506b8Sjruoho } 91528c506b8Sjruoho 91628c506b8Sjruoho /* Push scope for Resource Templates */ 91728c506b8Sjruoho 91828c506b8Sjruoho if (Op->Asl.ParseOpcode == PARSEOP_NAME) 91928c506b8Sjruoho { 920ae01dbf5Schristos if (Op->Asl.CompileFlags & OP_IS_RESOURCE_DESC) 92128c506b8Sjruoho { 92228c506b8Sjruoho ForceNewScope = TRUE; 92328c506b8Sjruoho } 92428c506b8Sjruoho } 92528c506b8Sjruoho 92628c506b8Sjruoho /* Push the scope stack */ 92728c506b8Sjruoho 92828c506b8Sjruoho if (ForceNewScope || AcpiNsOpensScope (ObjectType)) 92928c506b8Sjruoho { 93028c506b8Sjruoho Status = AcpiDsScopeStackPush (Node, ObjectType, WalkState); 93128c506b8Sjruoho if (ACPI_FAILURE (Status)) 93228c506b8Sjruoho { 93328c506b8Sjruoho return_ACPI_STATUS (Status); 93428c506b8Sjruoho } 93528c506b8Sjruoho } 93628c506b8Sjruoho 93728c506b8Sjruoho if (Op->Asl.ParseOpcode == PARSEOP_ALIAS) 93828c506b8Sjruoho { 93928c506b8Sjruoho /* Complete the alias node by getting and saving the target node */ 94028c506b8Sjruoho 94128c506b8Sjruoho /* First child is the alias target */ 94228c506b8Sjruoho 94328c506b8Sjruoho Arg = Op->Asl.Child; 94428c506b8Sjruoho 94528c506b8Sjruoho /* Get the target pathname */ 94628c506b8Sjruoho 94728c506b8Sjruoho Path = Arg->Asl.Namepath; 94828c506b8Sjruoho if (!Path) 94928c506b8Sjruoho { 95028c506b8Sjruoho Status = UtInternalizeName (Arg->Asl.ExternalName, &Path); 95128c506b8Sjruoho if (ACPI_FAILURE (Status)) 95228c506b8Sjruoho { 95328c506b8Sjruoho return (Status); 95428c506b8Sjruoho } 95528c506b8Sjruoho } 95628c506b8Sjruoho 95728c506b8Sjruoho /* Get the NS node associated with the target. It must exist. */ 95828c506b8Sjruoho 95928c506b8Sjruoho Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ACPI_TYPE_ANY, 96028c506b8Sjruoho ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE, 96128c506b8Sjruoho WalkState, &TargetNode); 96228c506b8Sjruoho if (ACPI_FAILURE (Status)) 96328c506b8Sjruoho { 96428c506b8Sjruoho if (Status == AE_NOT_FOUND) 96528c506b8Sjruoho { 96628c506b8Sjruoho AslError (ASL_ERROR, ASL_MSG_NOT_FOUND, Op, 96728c506b8Sjruoho Op->Asl.ExternalName); 96828c506b8Sjruoho 96928c506b8Sjruoho /* 97028c506b8Sjruoho * The name was not found, go ahead and create it. 97128c506b8Sjruoho * This prevents more errors later. 97228c506b8Sjruoho */ 97328c506b8Sjruoho Status = AcpiNsLookup (WalkState->ScopeInfo, Path, 97428c506b8Sjruoho ACPI_TYPE_ANY, 97528c506b8Sjruoho ACPI_IMODE_LOAD_PASS1, ACPI_NS_NO_UPSEARCH, 97628c506b8Sjruoho WalkState, &(Node)); 97728c506b8Sjruoho return (AE_OK); 97828c506b8Sjruoho } 97928c506b8Sjruoho 98028c506b8Sjruoho AslCoreSubsystemError (Op, Status, 98128c506b8Sjruoho "Failure from namespace lookup", FALSE); 98228c506b8Sjruoho return (AE_OK); 98328c506b8Sjruoho } 98428c506b8Sjruoho 98528c506b8Sjruoho /* Save the target node within the alias node */ 98628c506b8Sjruoho 98728c506b8Sjruoho Node->Object = ACPI_CAST_PTR (ACPI_OPERAND_OBJECT, TargetNode); 98828c506b8Sjruoho } 98928c506b8Sjruoho 99028c506b8Sjruoho return (AE_OK); 99128c506b8Sjruoho } 99228c506b8Sjruoho 99328c506b8Sjruoho 99428c506b8Sjruoho /******************************************************************************* 99528c506b8Sjruoho * 99628c506b8Sjruoho * FUNCTION: LdCommonNamespaceEnd 99728c506b8Sjruoho * 99828c506b8Sjruoho * PARAMETERS: ASL_WALK_CALLBACK 99928c506b8Sjruoho * 100028c506b8Sjruoho * RETURN: Status 100128c506b8Sjruoho * 100228c506b8Sjruoho * DESCRIPTION: Ascending callback used during the loading of the namespace, 100328c506b8Sjruoho * We only need to worry about managing the scope stack here. 100428c506b8Sjruoho * 100528c506b8Sjruoho ******************************************************************************/ 100628c506b8Sjruoho 100728c506b8Sjruoho static ACPI_STATUS 100828c506b8Sjruoho LdCommonNamespaceEnd ( 100928c506b8Sjruoho ACPI_PARSE_OBJECT *Op, 101028c506b8Sjruoho UINT32 Level, 101128c506b8Sjruoho void *Context) 101228c506b8Sjruoho { 101328c506b8Sjruoho ACPI_WALK_STATE *WalkState = (ACPI_WALK_STATE *) Context; 101428c506b8Sjruoho ACPI_OBJECT_TYPE ObjectType; 101528c506b8Sjruoho BOOLEAN ForceNewScope = FALSE; 101628c506b8Sjruoho 101728c506b8Sjruoho 101828c506b8Sjruoho ACPI_FUNCTION_NAME (LdCommonNamespaceEnd); 101928c506b8Sjruoho 102028c506b8Sjruoho 102128c506b8Sjruoho /* We are only interested in opcodes that have an associated name */ 102228c506b8Sjruoho 102328c506b8Sjruoho if (!Op->Asl.Namepath) 102428c506b8Sjruoho { 102528c506b8Sjruoho return (AE_OK); 102628c506b8Sjruoho } 102728c506b8Sjruoho 102828c506b8Sjruoho /* Get the type to determine if we should pop the scope */ 102928c506b8Sjruoho 103028c506b8Sjruoho if ((Op->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG) && 1031ae01dbf5Schristos (Op->Asl.CompileFlags == OP_IS_RESOURCE_DESC)) 103228c506b8Sjruoho { 103328c506b8Sjruoho /* TBD: Merge into AcpiDsMapNamedOpcodeToDataType */ 103428c506b8Sjruoho 103528c506b8Sjruoho ObjectType = ACPI_TYPE_LOCAL_RESOURCE; 103628c506b8Sjruoho } 103728c506b8Sjruoho else 103828c506b8Sjruoho { 103928c506b8Sjruoho ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode); 104028c506b8Sjruoho } 104128c506b8Sjruoho 104228c506b8Sjruoho /* Pop scope that was pushed for Resource Templates */ 104328c506b8Sjruoho 104428c506b8Sjruoho if (Op->Asl.ParseOpcode == PARSEOP_NAME) 104528c506b8Sjruoho { 1046ae01dbf5Schristos if (Op->Asl.CompileFlags & OP_IS_RESOURCE_DESC) 104728c506b8Sjruoho { 104828c506b8Sjruoho ForceNewScope = TRUE; 104928c506b8Sjruoho } 105028c506b8Sjruoho } 105128c506b8Sjruoho 105228c506b8Sjruoho /* Pop the scope stack */ 105328c506b8Sjruoho 105428c506b8Sjruoho if (ForceNewScope || AcpiNsOpensScope (ObjectType)) 105528c506b8Sjruoho { 105628c506b8Sjruoho ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, 105728c506b8Sjruoho "(%s): Popping scope for Op [%s] %p\n", 105828c506b8Sjruoho AcpiUtGetTypeName (ObjectType), Op->Asl.ParseOpName, Op)); 105928c506b8Sjruoho 106028c506b8Sjruoho (void) AcpiDsScopeStackPop (WalkState); 106128c506b8Sjruoho } 106228c506b8Sjruoho 106328c506b8Sjruoho return (AE_OK); 106428c506b8Sjruoho } 1065