128c506b8Sjruoho /****************************************************************************** 228c506b8Sjruoho * 328c506b8Sjruoho * Module Name: dswload - Dispatcher namespace load callbacks 428c506b8Sjruoho * 528c506b8Sjruoho *****************************************************************************/ 628c506b8Sjruoho 7124f4c82Sjruoho /* 8f45f09e8Schristos * Copyright (C) 2000 - 2018, 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" 48a40a9998Schristos #include "acparser.h" 4928c506b8Sjruoho #include "aslcompiler.y.h" 5028c506b8Sjruoho 51a40a9998Schristos 5228c506b8Sjruoho #define _COMPONENT ACPI_COMPILER 5328c506b8Sjruoho ACPI_MODULE_NAME ("aslload") 5428c506b8Sjruoho 5528c506b8Sjruoho /* Local prototypes */ 5628c506b8Sjruoho 5728c506b8Sjruoho static ACPI_STATUS 5828c506b8Sjruoho LdLoadFieldElements ( 5928c506b8Sjruoho ACPI_PARSE_OBJECT *Op, 6028c506b8Sjruoho ACPI_WALK_STATE *WalkState); 6128c506b8Sjruoho 6228c506b8Sjruoho static ACPI_STATUS 6328c506b8Sjruoho LdLoadResourceElements ( 6428c506b8Sjruoho ACPI_PARSE_OBJECT *Op, 6528c506b8Sjruoho ACPI_WALK_STATE *WalkState); 6628c506b8Sjruoho 6728c506b8Sjruoho static ACPI_STATUS 6828c506b8Sjruoho LdNamespace1Begin ( 6928c506b8Sjruoho ACPI_PARSE_OBJECT *Op, 7028c506b8Sjruoho UINT32 Level, 7128c506b8Sjruoho void *Context); 7228c506b8Sjruoho 7328c506b8Sjruoho static ACPI_STATUS 7428c506b8Sjruoho LdNamespace2Begin ( 7528c506b8Sjruoho ACPI_PARSE_OBJECT *Op, 7628c506b8Sjruoho UINT32 Level, 7728c506b8Sjruoho void *Context); 7828c506b8Sjruoho 7928c506b8Sjruoho static ACPI_STATUS 8028c506b8Sjruoho LdCommonNamespaceEnd ( 8128c506b8Sjruoho ACPI_PARSE_OBJECT *Op, 8228c506b8Sjruoho UINT32 Level, 8328c506b8Sjruoho void *Context); 8428c506b8Sjruoho 8528c506b8Sjruoho 8628c506b8Sjruoho /******************************************************************************* 8728c506b8Sjruoho * 8828c506b8Sjruoho * FUNCTION: LdLoadNamespace 8928c506b8Sjruoho * 9028c506b8Sjruoho * PARAMETERS: RootOp - Root of the parse tree 9128c506b8Sjruoho * 9228c506b8Sjruoho * RETURN: Status 9328c506b8Sjruoho * 9428c506b8Sjruoho * DESCRIPTION: Perform a walk of the parse tree that in turn loads all of the 9528c506b8Sjruoho * named ASL/AML objects into the namespace. The namespace is 9628c506b8Sjruoho * constructed in order to resolve named references and references 9728c506b8Sjruoho * to named fields within resource templates/descriptors. 9828c506b8Sjruoho * 9928c506b8Sjruoho ******************************************************************************/ 10028c506b8Sjruoho 10128c506b8Sjruoho ACPI_STATUS 10228c506b8Sjruoho LdLoadNamespace ( 10328c506b8Sjruoho ACPI_PARSE_OBJECT *RootOp) 10428c506b8Sjruoho { 10528c506b8Sjruoho ACPI_WALK_STATE *WalkState; 10628c506b8Sjruoho 10728c506b8Sjruoho 10828c506b8Sjruoho /* Create a new walk state */ 10928c506b8Sjruoho 11028c506b8Sjruoho WalkState = AcpiDsCreateWalkState (0, NULL, NULL, NULL); 11128c506b8Sjruoho if (!WalkState) 11228c506b8Sjruoho { 113ff4a156dSchristos return (AE_NO_MEMORY); 11428c506b8Sjruoho } 11528c506b8Sjruoho 11628c506b8Sjruoho /* Walk the entire parse tree, first pass */ 11728c506b8Sjruoho 11828c506b8Sjruoho TrWalkParseTree (RootOp, ASL_WALK_VISIT_TWICE, LdNamespace1Begin, 11928c506b8Sjruoho LdCommonNamespaceEnd, WalkState); 12028c506b8Sjruoho 12128c506b8Sjruoho /* Second pass to handle forward references */ 12228c506b8Sjruoho 12328c506b8Sjruoho TrWalkParseTree (RootOp, ASL_WALK_VISIT_TWICE, LdNamespace2Begin, 12428c506b8Sjruoho LdCommonNamespaceEnd, WalkState); 12528c506b8Sjruoho 12628c506b8Sjruoho /* Dump the namespace if debug is enabled */ 12728c506b8Sjruoho 128a147b75fSchristos if (AcpiDbgLevel & ACPI_LV_TABLES) 129a147b75fSchristos { 13028c506b8Sjruoho AcpiNsDumpTables (ACPI_NS_ALL, ACPI_UINT32_MAX); 131a147b75fSchristos } 132a147b75fSchristos 133414ef032Schristos ACPI_FREE (WalkState); 134ff4a156dSchristos return (AE_OK); 13528c506b8Sjruoho } 13628c506b8Sjruoho 13728c506b8Sjruoho 13828c506b8Sjruoho /******************************************************************************* 13928c506b8Sjruoho * 14028c506b8Sjruoho * FUNCTION: LdLoadFieldElements 14128c506b8Sjruoho * 14228c506b8Sjruoho * PARAMETERS: Op - Parent node (Field) 14328c506b8Sjruoho * WalkState - Current walk state 14428c506b8Sjruoho * 14528c506b8Sjruoho * RETURN: Status 14628c506b8Sjruoho * 14728c506b8Sjruoho * DESCRIPTION: Enter the named elements of the field (children of the parent) 14828c506b8Sjruoho * into the namespace. 14928c506b8Sjruoho * 15028c506b8Sjruoho ******************************************************************************/ 15128c506b8Sjruoho 15228c506b8Sjruoho static ACPI_STATUS 15328c506b8Sjruoho LdLoadFieldElements ( 15428c506b8Sjruoho ACPI_PARSE_OBJECT *Op, 15528c506b8Sjruoho ACPI_WALK_STATE *WalkState) 15628c506b8Sjruoho { 15728c506b8Sjruoho ACPI_PARSE_OBJECT *Child = NULL; 15828c506b8Sjruoho ACPI_NAMESPACE_NODE *Node; 15928c506b8Sjruoho ACPI_STATUS Status; 16028c506b8Sjruoho 16128c506b8Sjruoho 16228c506b8Sjruoho /* Get the first named field element */ 16328c506b8Sjruoho 16428c506b8Sjruoho switch (Op->Asl.AmlOpcode) 16528c506b8Sjruoho { 16628c506b8Sjruoho case AML_BANK_FIELD_OP: 16728c506b8Sjruoho 16828c506b8Sjruoho Child = UtGetArg (Op, 6); 16928c506b8Sjruoho break; 17028c506b8Sjruoho 17128c506b8Sjruoho case AML_INDEX_FIELD_OP: 17228c506b8Sjruoho 17328c506b8Sjruoho Child = UtGetArg (Op, 5); 17428c506b8Sjruoho break; 17528c506b8Sjruoho 17628c506b8Sjruoho case AML_FIELD_OP: 17728c506b8Sjruoho 17828c506b8Sjruoho Child = UtGetArg (Op, 4); 17928c506b8Sjruoho break; 18028c506b8Sjruoho 18128c506b8Sjruoho default: 182ff4a156dSchristos 18328c506b8Sjruoho /* No other opcodes should arrive here */ 184ff4a156dSchristos 18528c506b8Sjruoho return (AE_BAD_PARAMETER); 18628c506b8Sjruoho } 18728c506b8Sjruoho 18828c506b8Sjruoho /* Enter all elements into the namespace */ 18928c506b8Sjruoho 19028c506b8Sjruoho while (Child) 19128c506b8Sjruoho { 19228c506b8Sjruoho switch (Child->Asl.AmlOpcode) 19328c506b8Sjruoho { 19428c506b8Sjruoho case AML_INT_RESERVEDFIELD_OP: 19528c506b8Sjruoho case AML_INT_ACCESSFIELD_OP: 196ff4a156dSchristos case AML_INT_CONNECTION_OP: 19728c506b8Sjruoho break; 19828c506b8Sjruoho 19928c506b8Sjruoho default: 20028c506b8Sjruoho 20128c506b8Sjruoho Status = AcpiNsLookup (WalkState->ScopeInfo, 20228c506b8Sjruoho Child->Asl.Value.String, 20328c506b8Sjruoho ACPI_TYPE_LOCAL_REGION_FIELD, 20428c506b8Sjruoho ACPI_IMODE_LOAD_PASS1, 20528c506b8Sjruoho ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE | 20681bd9c9cSchristos ACPI_NS_ERROR_IF_FOUND, NULL, &Node); 20728c506b8Sjruoho if (ACPI_FAILURE (Status)) 20828c506b8Sjruoho { 20928c506b8Sjruoho if (Status != AE_ALREADY_EXISTS) 21028c506b8Sjruoho { 21128c506b8Sjruoho AslError (ASL_ERROR, ASL_MSG_CORE_EXCEPTION, Child, 21228c506b8Sjruoho Child->Asl.Value.String); 21328c506b8Sjruoho return (Status); 21428c506b8Sjruoho } 215ae01dbf5Schristos else if (Status == AE_ALREADY_EXISTS && 216a147b75fSchristos (Node->Flags & ANOBJ_IS_EXTERNAL)) 217ae01dbf5Schristos { 218ae01dbf5Schristos Node->Type = (UINT8) ACPI_TYPE_LOCAL_REGION_FIELD; 219ae01dbf5Schristos } 220ae01dbf5Schristos else 221ae01dbf5Schristos { 22228c506b8Sjruoho /* 22328c506b8Sjruoho * The name already exists in this scope 22428c506b8Sjruoho * But continue processing the elements 22528c506b8Sjruoho */ 226f45f09e8Schristos AslDualParseOpError (ASL_WARNING, ASL_MSG_EXTERN_COLLISION, Child, 227f45f09e8Schristos Child->Asl.Value.String, ASL_MSG_EXTERN_FOUND_HERE, Node->Op, 22825666a51Schristos Node->Op->Asl.ExternalName); 22928c506b8Sjruoho } 230ae01dbf5Schristos } 23128c506b8Sjruoho else 23228c506b8Sjruoho { 23328c506b8Sjruoho Child->Asl.Node = Node; 23428c506b8Sjruoho Node->Op = Child; 23528c506b8Sjruoho } 23628c506b8Sjruoho break; 23728c506b8Sjruoho } 238ff4a156dSchristos 23928c506b8Sjruoho Child = Child->Asl.Next; 24028c506b8Sjruoho } 241ff4a156dSchristos 24228c506b8Sjruoho return (AE_OK); 24328c506b8Sjruoho } 24428c506b8Sjruoho 24528c506b8Sjruoho 24628c506b8Sjruoho /******************************************************************************* 24728c506b8Sjruoho * 24828c506b8Sjruoho * FUNCTION: LdLoadResourceElements 24928c506b8Sjruoho * 25028c506b8Sjruoho * PARAMETERS: Op - Parent node (Resource Descriptor) 25128c506b8Sjruoho * WalkState - Current walk state 25228c506b8Sjruoho * 25328c506b8Sjruoho * RETURN: Status 25428c506b8Sjruoho * 25528c506b8Sjruoho * DESCRIPTION: Enter the named elements of the resource descriptor (children 25628c506b8Sjruoho * of the parent) into the namespace. 25728c506b8Sjruoho * 25828c506b8Sjruoho * NOTE: In the real AML namespace, these named elements never exist. But 25928c506b8Sjruoho * we simply use the namespace here as a symbol table so we can look 26028c506b8Sjruoho * them up as they are referenced. 26128c506b8Sjruoho * 26228c506b8Sjruoho ******************************************************************************/ 26328c506b8Sjruoho 26428c506b8Sjruoho static ACPI_STATUS 26528c506b8Sjruoho LdLoadResourceElements ( 26628c506b8Sjruoho ACPI_PARSE_OBJECT *Op, 26728c506b8Sjruoho ACPI_WALK_STATE *WalkState) 26828c506b8Sjruoho { 26928c506b8Sjruoho ACPI_PARSE_OBJECT *InitializerOp = NULL; 27028c506b8Sjruoho ACPI_NAMESPACE_NODE *Node; 27128c506b8Sjruoho ACPI_STATUS Status; 27228c506b8Sjruoho 27328c506b8Sjruoho 27428c506b8Sjruoho /* 27528c506b8Sjruoho * Enter the resource name into the namespace. Name must not already exist. 27628c506b8Sjruoho * This opens a scope, so later field names are guaranteed to be new/unique. 27728c506b8Sjruoho */ 27828c506b8Sjruoho Status = AcpiNsLookup (WalkState->ScopeInfo, Op->Asl.Namepath, 27928c506b8Sjruoho ACPI_TYPE_LOCAL_RESOURCE, ACPI_IMODE_LOAD_PASS1, 28028c506b8Sjruoho ACPI_NS_NO_UPSEARCH | ACPI_NS_ERROR_IF_FOUND, 28128c506b8Sjruoho WalkState, &Node); 28228c506b8Sjruoho if (ACPI_FAILURE (Status)) 28328c506b8Sjruoho { 28428c506b8Sjruoho if (Status == AE_ALREADY_EXISTS) 28528c506b8Sjruoho { 28628c506b8Sjruoho /* Actual node causing the error was saved in ParentMethod */ 28728c506b8Sjruoho 28825666a51Schristos AslDualParseOpError (ASL_ERROR, ASL_MSG_NAME_EXISTS, 28925666a51Schristos (ACPI_PARSE_OBJECT *) Op->Asl.ParentMethod, 29025666a51Schristos Op->Asl.Namepath, ASL_MSG_FOUND_HERE, Node->Op, 29125666a51Schristos Node->Op->Asl.ExternalName); 29228c506b8Sjruoho return (AE_OK); 29328c506b8Sjruoho } 29428c506b8Sjruoho return (Status); 29528c506b8Sjruoho } 29628c506b8Sjruoho 29728c506b8Sjruoho Node->Value = (UINT32) Op->Asl.Value.Integer; 29828c506b8Sjruoho Node->Op = Op; 29928c506b8Sjruoho Op->Asl.Node = Node; 30028c506b8Sjruoho 30128c506b8Sjruoho /* 30228c506b8Sjruoho * Now enter the predefined fields, for easy lookup when referenced 30328c506b8Sjruoho * by the source ASL 30428c506b8Sjruoho */ 30528c506b8Sjruoho InitializerOp = ASL_GET_CHILD_NODE (Op); 30628c506b8Sjruoho while (InitializerOp) 30728c506b8Sjruoho { 30828c506b8Sjruoho if (InitializerOp->Asl.ExternalName) 30928c506b8Sjruoho { 31028c506b8Sjruoho Status = AcpiNsLookup (WalkState->ScopeInfo, 31128c506b8Sjruoho InitializerOp->Asl.ExternalName, 312*7efa3256Schristos ACPI_TYPE_LOCAL_RESOURCE_FIELD, ACPI_IMODE_LOAD_PASS1, 313*7efa3256Schristos ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE, NULL, &Node); 31428c506b8Sjruoho if (ACPI_FAILURE (Status)) 31528c506b8Sjruoho { 31628c506b8Sjruoho return (Status); 31728c506b8Sjruoho } 31828c506b8Sjruoho 31928c506b8Sjruoho /* 320ff4a156dSchristos * Store the field offset and length in the namespace node 321ff4a156dSchristos * so it can be used when the field is referenced 32228c506b8Sjruoho */ 323ff4a156dSchristos Node->Value = InitializerOp->Asl.Value.Tag.BitOffset; 324ff4a156dSchristos Node->Length = InitializerOp->Asl.Value.Tag.BitLength; 32528c506b8Sjruoho InitializerOp->Asl.Node = Node; 32628c506b8Sjruoho Node->Op = InitializerOp; 32728c506b8Sjruoho } 328ff4a156dSchristos 32928c506b8Sjruoho InitializerOp = ASL_GET_PEER_NODE (InitializerOp); 33028c506b8Sjruoho } 33128c506b8Sjruoho 33228c506b8Sjruoho return (AE_OK); 33328c506b8Sjruoho } 33428c506b8Sjruoho 33528c506b8Sjruoho 33628c506b8Sjruoho /******************************************************************************* 33728c506b8Sjruoho * 33828c506b8Sjruoho * FUNCTION: LdNamespace1Begin 33928c506b8Sjruoho * 34028c506b8Sjruoho * PARAMETERS: ASL_WALK_CALLBACK 34128c506b8Sjruoho * 34228c506b8Sjruoho * RETURN: Status 34328c506b8Sjruoho * 34428c506b8Sjruoho * DESCRIPTION: Descending callback used during the parse tree walk. If this 34528c506b8Sjruoho * is a named AML opcode, enter into the namespace 34628c506b8Sjruoho * 34728c506b8Sjruoho ******************************************************************************/ 34828c506b8Sjruoho 34928c506b8Sjruoho static ACPI_STATUS 35028c506b8Sjruoho LdNamespace1Begin ( 35128c506b8Sjruoho ACPI_PARSE_OBJECT *Op, 35228c506b8Sjruoho UINT32 Level, 35328c506b8Sjruoho void *Context) 35428c506b8Sjruoho { 35528c506b8Sjruoho ACPI_WALK_STATE *WalkState = (ACPI_WALK_STATE *) Context; 35628c506b8Sjruoho ACPI_NAMESPACE_NODE *Node; 35781bd9c9cSchristos ACPI_PARSE_OBJECT *MethodOp; 35828c506b8Sjruoho ACPI_STATUS Status; 35928c506b8Sjruoho ACPI_OBJECT_TYPE ObjectType; 36028c506b8Sjruoho ACPI_OBJECT_TYPE ActualObjectType = ACPI_TYPE_ANY; 36128c506b8Sjruoho char *Path; 36228c506b8Sjruoho UINT32 Flags = ACPI_NS_NO_UPSEARCH; 36328c506b8Sjruoho ACPI_PARSE_OBJECT *Arg; 36428c506b8Sjruoho UINT32 i; 36528c506b8Sjruoho BOOLEAN ForceNewScope = FALSE; 366a40a9998Schristos const ACPI_OPCODE_INFO *OpInfo; 367a40a9998Schristos ACPI_PARSE_OBJECT *ParentOp; 36828c506b8Sjruoho 36928c506b8Sjruoho 37028c506b8Sjruoho ACPI_FUNCTION_NAME (LdNamespace1Begin); 371a40a9998Schristos 372a40a9998Schristos 37328c506b8Sjruoho ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Op %p [%s]\n", 37428c506b8Sjruoho Op, Op->Asl.ParseOpName)); 37528c506b8Sjruoho 37628c506b8Sjruoho /* 37728c506b8Sjruoho * We are only interested in opcodes that have an associated name 37828c506b8Sjruoho * (or multiple names) 37928c506b8Sjruoho */ 38028c506b8Sjruoho switch (Op->Asl.AmlOpcode) 38128c506b8Sjruoho { 38228c506b8Sjruoho case AML_BANK_FIELD_OP: 38328c506b8Sjruoho case AML_INDEX_FIELD_OP: 38428c506b8Sjruoho case AML_FIELD_OP: 38528c506b8Sjruoho 38628c506b8Sjruoho Status = LdLoadFieldElements (Op, WalkState); 38728c506b8Sjruoho return (Status); 38828c506b8Sjruoho 389414ef032Schristos case AML_INT_CONNECTION_OP: 390414ef032Schristos 391414ef032Schristos 392414ef032Schristos if (Op->Asl.Child->Asl.AmlOpcode != AML_INT_NAMEPATH_OP) 393414ef032Schristos { 394414ef032Schristos break; 395414ef032Schristos } 396414ef032Schristos Arg = Op->Asl.Child; 397414ef032Schristos 398414ef032Schristos Status = AcpiNsLookup (WalkState->ScopeInfo, Arg->Asl.ExternalName, 399414ef032Schristos ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT, 400414ef032Schristos WalkState, &Node); 401414ef032Schristos if (ACPI_FAILURE (Status)) 402414ef032Schristos { 403414ef032Schristos break; 404414ef032Schristos } 405414ef032Schristos 406414ef032Schristos if (Node->Type == ACPI_TYPE_BUFFER) 407414ef032Schristos { 408414ef032Schristos Arg->Asl.Node = Node; 409414ef032Schristos 410414ef032Schristos Arg = Node->Op->Asl.Child; /* Get namepath */ 411414ef032Schristos Arg = Arg->Asl.Next; /* Get actual buffer */ 412414ef032Schristos Arg = Arg->Asl.Child; /* Buffer length */ 413414ef032Schristos Arg = Arg->Asl.Next; /* RAW_DATA buffer */ 414414ef032Schristos } 415414ef032Schristos break; 416414ef032Schristos 41728c506b8Sjruoho default: 41828c506b8Sjruoho 41928c506b8Sjruoho /* All other opcodes go below */ 420ff4a156dSchristos 42128c506b8Sjruoho break; 42228c506b8Sjruoho } 42328c506b8Sjruoho 42428c506b8Sjruoho /* Check if this object has already been installed in the namespace */ 42528c506b8Sjruoho 42628c506b8Sjruoho if (Op->Asl.Node) 42728c506b8Sjruoho { 42828c506b8Sjruoho return (AE_OK); 42928c506b8Sjruoho } 43028c506b8Sjruoho 431a40a9998Schristos /* Check for a possible illegal forward reference */ 432a40a9998Schristos 433a40a9998Schristos if ((Op->Asl.ParseOpcode == PARSEOP_NAMESEG) || 434a40a9998Schristos (Op->Asl.ParseOpcode == PARSEOP_NAMESTRING)) 435a40a9998Schristos { 436a40a9998Schristos /* 437a40a9998Schristos * Op->Asl.Namepath will be NULL for these opcodes. 438a40a9998Schristos * These opcodes are guaranteed to have a parent. 439a40a9998Schristos * Examine the parent opcode. 440a40a9998Schristos */ 441a40a9998Schristos Status = AE_OK; 442a40a9998Schristos ParentOp = Op->Asl.Parent; 443a40a9998Schristos OpInfo = AcpiPsGetOpcodeInfo (ParentOp->Asl.AmlOpcode); 444a40a9998Schristos 445a40a9998Schristos /* 446a40a9998Schristos * Exclude all operators that actually declare a new name: 447a40a9998Schristos * Name (ABCD, 1) -> Ignore (AML_CLASS_NAMED_OBJECT) 448a40a9998Schristos * We only want references to named objects: 449a40a9998Schristos * Store (2, WXYZ) -> Attempt to resolve the name 450a40a9998Schristos */ 451a40a9998Schristos if (OpInfo->Class == AML_CLASS_NAMED_OBJECT) 452a40a9998Schristos { 453a40a9998Schristos return (AE_OK); 454a40a9998Schristos } 455a40a9998Schristos 456a40a9998Schristos /* 457a40a9998Schristos * Check if the referenced object exists at this point during 458a40a9998Schristos * the load: 459a40a9998Schristos * 1) If it exists, then this cannot be a forward reference. 460a40a9998Schristos * 2) If it does not exist, it could be a forward reference or 461a40a9998Schristos * it truly does not exist (and no external declaration). 462a40a9998Schristos */ 463a40a9998Schristos Status = AcpiNsLookup (WalkState->ScopeInfo, 464a40a9998Schristos Op->Asl.Value.Name, ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE, 465a40a9998Schristos ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE, 466a40a9998Schristos WalkState, &Node); 467a40a9998Schristos if (Status == AE_NOT_FOUND) 468a40a9998Schristos { 469a40a9998Schristos /* 470a40a9998Schristos * This is either a foward reference or the object truly 471a40a9998Schristos * does not exist. The two cases can only be differentiated 472a40a9998Schristos * during the cross-reference stage later. Mark the Op/Name 473a40a9998Schristos * as not-found for now to indicate the need for further 474a40a9998Schristos * processing. 475a40a9998Schristos * 476a40a9998Schristos * Special case: Allow forward references from elements of 477a40a9998Schristos * Package objects. This provides compatibility with other 478a40a9998Schristos * ACPI implementations. To correctly implement this, the 479a40a9998Schristos * ACPICA table load defers package resolution until the entire 480a40a9998Schristos * namespace has been loaded. 481a40a9998Schristos */ 482a40a9998Schristos if ((ParentOp->Asl.ParseOpcode != PARSEOP_PACKAGE) && 483a40a9998Schristos (ParentOp->Asl.ParseOpcode != PARSEOP_VAR_PACKAGE)) 484a40a9998Schristos { 485a40a9998Schristos Op->Asl.CompileFlags |= OP_NOT_FOUND_DURING_LOAD; 486a40a9998Schristos } 487a40a9998Schristos 488a40a9998Schristos return (AE_OK); 489a40a9998Schristos } 490a40a9998Schristos 491a40a9998Schristos return (Status); 492a40a9998Schristos } 493a40a9998Schristos 49428c506b8Sjruoho Path = Op->Asl.Namepath; 49528c506b8Sjruoho if (!Path) 49628c506b8Sjruoho { 49728c506b8Sjruoho return (AE_OK); 49828c506b8Sjruoho } 49928c506b8Sjruoho 50028c506b8Sjruoho /* Map the raw opcode into an internal object type */ 50128c506b8Sjruoho 50228c506b8Sjruoho switch (Op->Asl.ParseOpcode) 50328c506b8Sjruoho { 50428c506b8Sjruoho case PARSEOP_NAME: 50528c506b8Sjruoho 50628c506b8Sjruoho Arg = Op->Asl.Child; /* Get the NameSeg/NameString node */ 50728c506b8Sjruoho Arg = Arg->Asl.Next; /* First peer is the object to be associated with the name */ 50828c506b8Sjruoho 50928c506b8Sjruoho /* 51028c506b8Sjruoho * If this name refers to a ResourceTemplate, we will need to open 51128c506b8Sjruoho * a new scope so that the resource subfield names can be entered into 51228c506b8Sjruoho * the namespace underneath this name 51328c506b8Sjruoho */ 514ae01dbf5Schristos if (Op->Asl.CompileFlags & OP_IS_RESOURCE_DESC) 51528c506b8Sjruoho { 51628c506b8Sjruoho ForceNewScope = TRUE; 51728c506b8Sjruoho } 51828c506b8Sjruoho 51928c506b8Sjruoho /* Get the data type associated with the named object, not the name itself */ 52028c506b8Sjruoho 52128c506b8Sjruoho /* Log2 loop to convert from Btype (binary) to Etype (encoded) */ 52228c506b8Sjruoho 52328c506b8Sjruoho ObjectType = 1; 52428c506b8Sjruoho for (i = 1; i < Arg->Asl.AcpiBtype; i *= 2) 52528c506b8Sjruoho { 52628c506b8Sjruoho ObjectType++; 52728c506b8Sjruoho } 52828c506b8Sjruoho break; 52928c506b8Sjruoho 53028c506b8Sjruoho case PARSEOP_EXTERNAL: 53128c506b8Sjruoho /* 53228c506b8Sjruoho * "External" simply enters a name and type into the namespace. 53328c506b8Sjruoho * We must be careful to not open a new scope, however, no matter 53428c506b8Sjruoho * what type the external name refers to (e.g., a method) 53528c506b8Sjruoho * 53628c506b8Sjruoho * first child is name, next child is ObjectType 53728c506b8Sjruoho */ 53828c506b8Sjruoho ActualObjectType = (UINT8) Op->Asl.Child->Asl.Next->Asl.Value.Integer; 53928c506b8Sjruoho ObjectType = ACPI_TYPE_ANY; 54028c506b8Sjruoho 54128c506b8Sjruoho /* 54228c506b8Sjruoho * We will mark every new node along the path as "External". This 54328c506b8Sjruoho * allows some or all of the nodes to be created later in the ASL 54428c506b8Sjruoho * code. Handles cases like this: 54528c506b8Sjruoho * 54628c506b8Sjruoho * External (\_SB_.PCI0.ABCD, IntObj) 54728c506b8Sjruoho * Scope (_SB_) 54828c506b8Sjruoho * { 54928c506b8Sjruoho * Device (PCI0) 55028c506b8Sjruoho * { 55128c506b8Sjruoho * } 55228c506b8Sjruoho * } 55328c506b8Sjruoho * Method (X) 55428c506b8Sjruoho * { 55528c506b8Sjruoho * Store (\_SB_.PCI0.ABCD, Local0) 55628c506b8Sjruoho * } 55728c506b8Sjruoho */ 55828c506b8Sjruoho Flags |= ACPI_NS_EXTERNAL; 55928c506b8Sjruoho break; 56028c506b8Sjruoho 56128c506b8Sjruoho case PARSEOP_DEFAULT_ARG: 56228c506b8Sjruoho 563ae01dbf5Schristos if (Op->Asl.CompileFlags == OP_IS_RESOURCE_DESC) 56428c506b8Sjruoho { 56528c506b8Sjruoho Status = LdLoadResourceElements (Op, WalkState); 56628c506b8Sjruoho return_ACPI_STATUS (Status); 56728c506b8Sjruoho } 56828c506b8Sjruoho 56928c506b8Sjruoho ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode); 57028c506b8Sjruoho break; 57128c506b8Sjruoho 57228c506b8Sjruoho case PARSEOP_SCOPE: 57328c506b8Sjruoho /* 57428c506b8Sjruoho * The name referenced by Scope(Name) must already exist at this point. 57528c506b8Sjruoho * In other words, forward references for Scope() are not supported. 57628c506b8Sjruoho * The only real reason for this is that the MS interpreter cannot 57728c506b8Sjruoho * handle this case. Perhaps someday this case can go away. 57828c506b8Sjruoho */ 57928c506b8Sjruoho Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ACPI_TYPE_ANY, 580*7efa3256Schristos ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT, WalkState, &Node); 58128c506b8Sjruoho if (ACPI_FAILURE (Status)) 58228c506b8Sjruoho { 58328c506b8Sjruoho if (Status == AE_NOT_FOUND) 58428c506b8Sjruoho { 58528c506b8Sjruoho /* The name was not found, go ahead and create it */ 58628c506b8Sjruoho 58728c506b8Sjruoho Status = AcpiNsLookup (WalkState->ScopeInfo, Path, 588*7efa3256Schristos ACPI_TYPE_LOCAL_SCOPE, ACPI_IMODE_LOAD_PASS1, 589*7efa3256Schristos Flags, WalkState, &Node); 590ff4a156dSchristos if (ACPI_FAILURE (Status)) 591ff4a156dSchristos { 592ff4a156dSchristos return_ACPI_STATUS (Status); 593ff4a156dSchristos } 59428c506b8Sjruoho 595*7efa3256Schristos /* However, this is an error -- operand to Scope must exist */ 596*7efa3256Schristos 597*7efa3256Schristos if (strlen (Op->Asl.ExternalName) == ACPI_NAME_SIZE) 598*7efa3256Schristos { 59928c506b8Sjruoho AslError (ASL_ERROR, ASL_MSG_NOT_FOUND, Op, 60028c506b8Sjruoho Op->Asl.ExternalName); 601*7efa3256Schristos } 602*7efa3256Schristos else 603*7efa3256Schristos { 604*7efa3256Schristos AslError (ASL_ERROR, ASL_MSG_NAMEPATH_NOT_EXIST, Op, 60528c506b8Sjruoho Op->Asl.ExternalName); 606*7efa3256Schristos } 607*7efa3256Schristos 60828c506b8Sjruoho goto FinishNode; 60928c506b8Sjruoho } 61028c506b8Sjruoho 61128c506b8Sjruoho AslCoreSubsystemError (Op, Status, 61228c506b8Sjruoho "Failure from namespace lookup", FALSE); 61328c506b8Sjruoho 61428c506b8Sjruoho return_ACPI_STATUS (Status); 61528c506b8Sjruoho } 61681bd9c9cSchristos else /* Status AE_OK */ 61781bd9c9cSchristos { 61881bd9c9cSchristos /* 61981bd9c9cSchristos * Do not allow references to external scopes from the DSDT. 62081bd9c9cSchristos * This is because the DSDT is always loaded first, and the 62181bd9c9cSchristos * external reference cannot be resolved -- causing a runtime 62281bd9c9cSchristos * error because Scope() must be resolved immediately. 62381bd9c9cSchristos * 10/2015. 62481bd9c9cSchristos */ 62581bd9c9cSchristos if ((Node->Flags & ANOBJ_IS_EXTERNAL) && 626*7efa3256Schristos (ACPI_COMPARE_NAME (AslGbl_TableSignature, "DSDT"))) 62781bd9c9cSchristos { 62881bd9c9cSchristos /* However, allowed if the reference is within a method */ 62981bd9c9cSchristos 63081bd9c9cSchristos MethodOp = Op->Asl.Parent; 63181bd9c9cSchristos while (MethodOp && 63281bd9c9cSchristos (MethodOp->Asl.ParseOpcode != PARSEOP_METHOD)) 63381bd9c9cSchristos { 63481bd9c9cSchristos MethodOp = MethodOp->Asl.Parent; 63581bd9c9cSchristos } 63681bd9c9cSchristos 63781bd9c9cSchristos if (!MethodOp) 63881bd9c9cSchristos { 63981bd9c9cSchristos /* Not in a control method, error */ 64081bd9c9cSchristos 64181bd9c9cSchristos AslError (ASL_ERROR, ASL_MSG_CROSS_TABLE_SCOPE, Op, NULL); 64281bd9c9cSchristos } 64381bd9c9cSchristos } 64481bd9c9cSchristos } 64528c506b8Sjruoho 64628c506b8Sjruoho /* We found a node with this name, now check the type */ 64728c506b8Sjruoho 64828c506b8Sjruoho switch (Node->Type) 64928c506b8Sjruoho { 65028c506b8Sjruoho case ACPI_TYPE_LOCAL_SCOPE: 65128c506b8Sjruoho case ACPI_TYPE_DEVICE: 65228c506b8Sjruoho case ACPI_TYPE_POWER: 65328c506b8Sjruoho case ACPI_TYPE_PROCESSOR: 65428c506b8Sjruoho case ACPI_TYPE_THERMAL: 65528c506b8Sjruoho 65628c506b8Sjruoho /* These are acceptable types - they all open a new scope */ 65728c506b8Sjruoho break; 65828c506b8Sjruoho 65928c506b8Sjruoho case ACPI_TYPE_INTEGER: 66028c506b8Sjruoho case ACPI_TYPE_STRING: 66128c506b8Sjruoho case ACPI_TYPE_BUFFER: 66228c506b8Sjruoho /* 66328c506b8Sjruoho * These types we will allow, but we will change the type. 66428c506b8Sjruoho * This enables some existing code of the form: 66528c506b8Sjruoho * 66628c506b8Sjruoho * Name (DEB, 0) 66728c506b8Sjruoho * Scope (DEB) { ... } 66828c506b8Sjruoho * 66928c506b8Sjruoho * Which is used to workaround the fact that the MS interpreter 67028c506b8Sjruoho * does not allow Scope() forward references. 67128c506b8Sjruoho */ 672*7efa3256Schristos snprintf (AslGbl_MsgBuffer, sizeof(AslGbl_MsgBuffer), "%s [%s], changing type to [Scope]", 67328c506b8Sjruoho Op->Asl.ExternalName, AcpiUtGetTypeName (Node->Type)); 674*7efa3256Schristos AslError (ASL_REMARK, ASL_MSG_SCOPE_TYPE, Op, AslGbl_MsgBuffer); 67528c506b8Sjruoho 67628c506b8Sjruoho /* Switch the type to scope, open the new scope */ 67728c506b8Sjruoho 67828c506b8Sjruoho Node->Type = ACPI_TYPE_LOCAL_SCOPE; 67928c506b8Sjruoho Status = AcpiDsScopeStackPush (Node, ACPI_TYPE_LOCAL_SCOPE, 68028c506b8Sjruoho WalkState); 68128c506b8Sjruoho if (ACPI_FAILURE (Status)) 68228c506b8Sjruoho { 68328c506b8Sjruoho return_ACPI_STATUS (Status); 68428c506b8Sjruoho } 68528c506b8Sjruoho break; 68628c506b8Sjruoho 68728c506b8Sjruoho default: 68828c506b8Sjruoho 68928c506b8Sjruoho /* All other types are an error */ 69028c506b8Sjruoho 691*7efa3256Schristos snprintf (AslGbl_MsgBuffer, sizeof(AslGbl_MsgBuffer), "%s [%s]", Op->Asl.ExternalName, 69228c506b8Sjruoho AcpiUtGetTypeName (Node->Type)); 693*7efa3256Schristos AslError (ASL_ERROR, ASL_MSG_SCOPE_TYPE, Op, AslGbl_MsgBuffer); 69428c506b8Sjruoho 69528c506b8Sjruoho /* 69628c506b8Sjruoho * However, switch the type to be an actual scope so 69728c506b8Sjruoho * that compilation can continue without generating a whole 69828c506b8Sjruoho * cascade of additional errors. Open the new scope. 69928c506b8Sjruoho */ 70028c506b8Sjruoho Node->Type = ACPI_TYPE_LOCAL_SCOPE; 70128c506b8Sjruoho Status = AcpiDsScopeStackPush (Node, ACPI_TYPE_LOCAL_SCOPE, 70228c506b8Sjruoho WalkState); 70328c506b8Sjruoho if (ACPI_FAILURE (Status)) 70428c506b8Sjruoho { 70528c506b8Sjruoho return_ACPI_STATUS (Status); 70628c506b8Sjruoho } 70728c506b8Sjruoho break; 70828c506b8Sjruoho } 70928c506b8Sjruoho 71028c506b8Sjruoho Status = AE_OK; 71128c506b8Sjruoho goto FinishNode; 71228c506b8Sjruoho 71328c506b8Sjruoho default: 71428c506b8Sjruoho 71528c506b8Sjruoho ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode); 71628c506b8Sjruoho break; 71728c506b8Sjruoho } 71828c506b8Sjruoho 71928c506b8Sjruoho ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Loading name: %s, (%s)\n", 72028c506b8Sjruoho Op->Asl.ExternalName, AcpiUtGetTypeName (ObjectType))); 72128c506b8Sjruoho 72228c506b8Sjruoho /* The name must not already exist */ 72328c506b8Sjruoho 72428c506b8Sjruoho Flags |= ACPI_NS_ERROR_IF_FOUND; 72528c506b8Sjruoho 72628c506b8Sjruoho /* 727*7efa3256Schristos * For opcodes that enter new names into the namespace, 728*7efa3256Schristos * all prefix NameSegs must exist. 729*7efa3256Schristos */ 730*7efa3256Schristos WalkState->OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode); 731*7efa3256Schristos if (((WalkState->OpInfo->Flags & AML_NAMED) || 732*7efa3256Schristos (WalkState->OpInfo->Flags & AML_CREATE)) && 733*7efa3256Schristos (Op->Asl.AmlOpcode != AML_EXTERNAL_OP)) 734*7efa3256Schristos { 735*7efa3256Schristos Flags |= ACPI_NS_PREFIX_MUST_EXIST; 736*7efa3256Schristos } 737*7efa3256Schristos 738*7efa3256Schristos /* 73928c506b8Sjruoho * Enter the named type into the internal namespace. We enter the name 74028c506b8Sjruoho * as we go downward in the parse tree. Any necessary subobjects that 74128c506b8Sjruoho * involve arguments to the opcode must be created as we go back up the 74228c506b8Sjruoho * parse tree later. 74328c506b8Sjruoho */ 74428c506b8Sjruoho Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ObjectType, 74528c506b8Sjruoho ACPI_IMODE_LOAD_PASS1, Flags, WalkState, &Node); 74628c506b8Sjruoho if (ACPI_FAILURE (Status)) 74728c506b8Sjruoho { 74828c506b8Sjruoho if (Status == AE_ALREADY_EXISTS) 74928c506b8Sjruoho { 75028c506b8Sjruoho /* The name already exists in this scope */ 75128c506b8Sjruoho 75228c506b8Sjruoho if (Node->Type == ACPI_TYPE_LOCAL_SCOPE) 75328c506b8Sjruoho { 75428c506b8Sjruoho /* Allow multiple references to the same scope */ 75528c506b8Sjruoho 75628c506b8Sjruoho Node->Type = (UINT8) ObjectType; 75728c506b8Sjruoho Status = AE_OK; 75828c506b8Sjruoho } 75928c506b8Sjruoho else if ((Node->Flags & ANOBJ_IS_EXTERNAL) && 76028c506b8Sjruoho (Op->Asl.ParseOpcode != PARSEOP_EXTERNAL)) 76128c506b8Sjruoho { 76228c506b8Sjruoho /* 76328c506b8Sjruoho * Allow one create on an object or segment that was 764a147b75fSchristos * previously declared External 76528c506b8Sjruoho */ 76628c506b8Sjruoho Node->Flags &= ~ANOBJ_IS_EXTERNAL; 76728c506b8Sjruoho Node->Type = (UINT8) ObjectType; 76828c506b8Sjruoho 76928c506b8Sjruoho /* Just retyped a node, probably will need to open a scope */ 77028c506b8Sjruoho 77128c506b8Sjruoho if (AcpiNsOpensScope (ObjectType)) 77228c506b8Sjruoho { 77328c506b8Sjruoho Status = AcpiDsScopeStackPush (Node, ObjectType, WalkState); 77428c506b8Sjruoho if (ACPI_FAILURE (Status)) 77528c506b8Sjruoho { 77628c506b8Sjruoho return_ACPI_STATUS (Status); 77728c506b8Sjruoho } 77828c506b8Sjruoho } 77981bd9c9cSchristos 78081bd9c9cSchristos Status = AE_OK; 78181bd9c9cSchristos } 78281bd9c9cSchristos else if (!(Node->Flags & ANOBJ_IS_EXTERNAL) && 78381bd9c9cSchristos (Op->Asl.ParseOpcode == PARSEOP_EXTERNAL)) 78481bd9c9cSchristos { 78581bd9c9cSchristos /* 78681bd9c9cSchristos * Allow externals in same scope as the definition of the 78781bd9c9cSchristos * actual object. Similar to C. Allows multiple definition 788a147b75fSchristos * blocks that refer to each other in the same file. 78981bd9c9cSchristos */ 79028c506b8Sjruoho Status = AE_OK; 79128c506b8Sjruoho } 79249c2f1f4Schristos else if ((Node->Flags & ANOBJ_IS_EXTERNAL) && 79349c2f1f4Schristos (Op->Asl.ParseOpcode == PARSEOP_EXTERNAL) && 79449c2f1f4Schristos (ObjectType == ACPI_TYPE_ANY)) 79549c2f1f4Schristos { 796a147b75fSchristos /* Allow update of externals of unknown type. */ 79749c2f1f4Schristos 79849c2f1f4Schristos if (AcpiNsOpensScope (ActualObjectType)) 79949c2f1f4Schristos { 80049c2f1f4Schristos Node->Type = (UINT8) ActualObjectType; 80149c2f1f4Schristos Status = AE_OK; 80249c2f1f4Schristos } 80349c2f1f4Schristos else 80449c2f1f4Schristos { 805*7efa3256Schristos sprintf (AslGbl_MsgBuffer, "%s [%s]", Op->Asl.ExternalName, 80649c2f1f4Schristos AcpiUtGetTypeName (Node->Type)); 807*7efa3256Schristos AslError (ASL_ERROR, ASL_MSG_SCOPE_TYPE, Op, AslGbl_MsgBuffer); 80849c2f1f4Schristos return_ACPI_STATUS (AE_OK); 80949c2f1f4Schristos } 81049c2f1f4Schristos } 81128c506b8Sjruoho else 81228c506b8Sjruoho { 81328c506b8Sjruoho /* Valid error, object already exists */ 81428c506b8Sjruoho 81525666a51Schristos AslDualParseOpError (ASL_ERROR, ASL_MSG_NAME_EXISTS, Op, 81625666a51Schristos Op->Asl.ExternalName, ASL_MSG_FOUND_HERE, Node->Op, 81725666a51Schristos Node->Op->Asl.ExternalName); 81828c506b8Sjruoho return_ACPI_STATUS (AE_OK); 81928c506b8Sjruoho } 82028c506b8Sjruoho } 821*7efa3256Schristos else if (AE_NOT_FOUND) 822*7efa3256Schristos { 823*7efa3256Schristos /* 824*7efa3256Schristos * One or more prefix NameSegs of the NamePath do not exist 825*7efa3256Schristos * (all of them must exist). Attempt to continue compilation 826*7efa3256Schristos * by setting the current scope to the root. 827*7efa3256Schristos */ 828*7efa3256Schristos Node = AcpiGbl_RootNode; 829*7efa3256Schristos Status = AE_OK; 830*7efa3256Schristos } 83128c506b8Sjruoho else 83228c506b8Sjruoho { 833*7efa3256Schristos /* Flag all other errors as coming from the ACPICA core */ 834*7efa3256Schristos 83528c506b8Sjruoho AslCoreSubsystemError (Op, Status, 83628c506b8Sjruoho "Failure from namespace lookup", FALSE); 83728c506b8Sjruoho return_ACPI_STATUS (Status); 83828c506b8Sjruoho } 83928c506b8Sjruoho } 84028c506b8Sjruoho 84128c506b8Sjruoho if (ForceNewScope) 84228c506b8Sjruoho { 84328c506b8Sjruoho Status = AcpiDsScopeStackPush (Node, ObjectType, WalkState); 84428c506b8Sjruoho if (ACPI_FAILURE (Status)) 84528c506b8Sjruoho { 84628c506b8Sjruoho return_ACPI_STATUS (Status); 84728c506b8Sjruoho } 84828c506b8Sjruoho } 84928c506b8Sjruoho 85028c506b8Sjruoho FinishNode: 85128c506b8Sjruoho /* 85228c506b8Sjruoho * Point the parse node to the new namespace node, and point 85328c506b8Sjruoho * the Node back to the original Parse node 85428c506b8Sjruoho */ 85528c506b8Sjruoho Op->Asl.Node = Node; 85628c506b8Sjruoho Node->Op = Op; 85728c506b8Sjruoho 85828c506b8Sjruoho /* Set the actual data type if appropriate (EXTERNAL term only) */ 85928c506b8Sjruoho 86028c506b8Sjruoho if (ActualObjectType != ACPI_TYPE_ANY) 86128c506b8Sjruoho { 86228c506b8Sjruoho Node->Type = (UINT8) ActualObjectType; 86328c506b8Sjruoho Node->Value = ASL_EXTERNAL_METHOD; 86428c506b8Sjruoho } 86528c506b8Sjruoho 86628c506b8Sjruoho if (Op->Asl.ParseOpcode == PARSEOP_METHOD) 86728c506b8Sjruoho { 86828c506b8Sjruoho /* 86928c506b8Sjruoho * Get the method argument count from "Extra" and save 87028c506b8Sjruoho * it in the namespace node 87128c506b8Sjruoho */ 87228c506b8Sjruoho Node->Value = (UINT32) Op->Asl.Extra; 87328c506b8Sjruoho } 87428c506b8Sjruoho 87528c506b8Sjruoho return_ACPI_STATUS (Status); 87628c506b8Sjruoho } 87728c506b8Sjruoho 87828c506b8Sjruoho 87928c506b8Sjruoho /******************************************************************************* 88028c506b8Sjruoho * 88128c506b8Sjruoho * FUNCTION: LdNamespace2Begin 88228c506b8Sjruoho * 88328c506b8Sjruoho * PARAMETERS: ASL_WALK_CALLBACK 88428c506b8Sjruoho * 88528c506b8Sjruoho * RETURN: Status 88628c506b8Sjruoho * 88728c506b8Sjruoho * DESCRIPTION: Descending callback used during the pass 2 parse tree walk. 88828c506b8Sjruoho * Second pass resolves some forward references. 88928c506b8Sjruoho * 89028c506b8Sjruoho * Notes: 89128c506b8Sjruoho * Currently only needs to handle the Alias operator. 89228c506b8Sjruoho * Could be used to allow forward references from the Scope() operator, but 89328c506b8Sjruoho * the MS interpreter does not allow this, so this compiler does not either. 89428c506b8Sjruoho * 89528c506b8Sjruoho ******************************************************************************/ 89628c506b8Sjruoho 89728c506b8Sjruoho static ACPI_STATUS 89828c506b8Sjruoho LdNamespace2Begin ( 89928c506b8Sjruoho ACPI_PARSE_OBJECT *Op, 90028c506b8Sjruoho UINT32 Level, 90128c506b8Sjruoho void *Context) 90228c506b8Sjruoho { 90328c506b8Sjruoho ACPI_WALK_STATE *WalkState = (ACPI_WALK_STATE *) Context; 90428c506b8Sjruoho ACPI_STATUS Status; 90528c506b8Sjruoho ACPI_NAMESPACE_NODE *Node; 90628c506b8Sjruoho ACPI_OBJECT_TYPE ObjectType; 90728c506b8Sjruoho BOOLEAN ForceNewScope = FALSE; 90828c506b8Sjruoho ACPI_PARSE_OBJECT *Arg; 90928c506b8Sjruoho char *Path; 91028c506b8Sjruoho ACPI_NAMESPACE_NODE *TargetNode; 91128c506b8Sjruoho 91228c506b8Sjruoho 91328c506b8Sjruoho ACPI_FUNCTION_NAME (LdNamespace2Begin); 91428c506b8Sjruoho ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Op %p [%s]\n", 91528c506b8Sjruoho Op, Op->Asl.ParseOpName)); 91628c506b8Sjruoho 91728c506b8Sjruoho 91828c506b8Sjruoho /* Ignore Ops with no namespace node */ 91928c506b8Sjruoho 92028c506b8Sjruoho Node = Op->Asl.Node; 92128c506b8Sjruoho if (!Node) 92228c506b8Sjruoho { 92328c506b8Sjruoho return (AE_OK); 92428c506b8Sjruoho } 92528c506b8Sjruoho 92628c506b8Sjruoho /* Get the type to determine if we should push the scope */ 92728c506b8Sjruoho 92828c506b8Sjruoho if ((Op->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG) && 929ae01dbf5Schristos (Op->Asl.CompileFlags == OP_IS_RESOURCE_DESC)) 93028c506b8Sjruoho { 93128c506b8Sjruoho ObjectType = ACPI_TYPE_LOCAL_RESOURCE; 93228c506b8Sjruoho } 93328c506b8Sjruoho else 93428c506b8Sjruoho { 93528c506b8Sjruoho ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode); 93628c506b8Sjruoho } 93728c506b8Sjruoho 93828c506b8Sjruoho /* Push scope for Resource Templates */ 93928c506b8Sjruoho 94028c506b8Sjruoho if (Op->Asl.ParseOpcode == PARSEOP_NAME) 94128c506b8Sjruoho { 942ae01dbf5Schristos if (Op->Asl.CompileFlags & OP_IS_RESOURCE_DESC) 94328c506b8Sjruoho { 94428c506b8Sjruoho ForceNewScope = TRUE; 94528c506b8Sjruoho } 94628c506b8Sjruoho } 94728c506b8Sjruoho 94828c506b8Sjruoho /* Push the scope stack */ 94928c506b8Sjruoho 95028c506b8Sjruoho if (ForceNewScope || AcpiNsOpensScope (ObjectType)) 95128c506b8Sjruoho { 95228c506b8Sjruoho Status = AcpiDsScopeStackPush (Node, ObjectType, WalkState); 95328c506b8Sjruoho if (ACPI_FAILURE (Status)) 95428c506b8Sjruoho { 95528c506b8Sjruoho return_ACPI_STATUS (Status); 95628c506b8Sjruoho } 95728c506b8Sjruoho } 95828c506b8Sjruoho 95928c506b8Sjruoho if (Op->Asl.ParseOpcode == PARSEOP_ALIAS) 96028c506b8Sjruoho { 961*7efa3256Schristos /* 962*7efa3256Schristos * Complete the alias node by getting and saving the target node. 963*7efa3256Schristos * First child is the alias target 964*7efa3256Schristos */ 96528c506b8Sjruoho Arg = Op->Asl.Child; 96628c506b8Sjruoho 96728c506b8Sjruoho /* Get the target pathname */ 96828c506b8Sjruoho 96928c506b8Sjruoho Path = Arg->Asl.Namepath; 97028c506b8Sjruoho if (!Path) 97128c506b8Sjruoho { 97228c506b8Sjruoho Status = UtInternalizeName (Arg->Asl.ExternalName, &Path); 97328c506b8Sjruoho if (ACPI_FAILURE (Status)) 97428c506b8Sjruoho { 97528c506b8Sjruoho return (Status); 97628c506b8Sjruoho } 97728c506b8Sjruoho } 97828c506b8Sjruoho 97928c506b8Sjruoho /* Get the NS node associated with the target. It must exist. */ 98028c506b8Sjruoho 98128c506b8Sjruoho Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ACPI_TYPE_ANY, 98228c506b8Sjruoho ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE, 98328c506b8Sjruoho WalkState, &TargetNode); 98428c506b8Sjruoho if (ACPI_FAILURE (Status)) 98528c506b8Sjruoho { 98628c506b8Sjruoho if (Status == AE_NOT_FOUND) 98728c506b8Sjruoho { 988*7efa3256Schristos /* Standalone NameSeg vs. NamePath */ 98928c506b8Sjruoho 990*7efa3256Schristos if (strlen (Arg->Asl.ExternalName) == ACPI_NAME_SIZE) 991*7efa3256Schristos { 992*7efa3256Schristos AslError (ASL_ERROR, ASL_MSG_NOT_FOUND, Op, 993*7efa3256Schristos Arg->Asl.ExternalName); 994*7efa3256Schristos } 995*7efa3256Schristos else 996*7efa3256Schristos { 997*7efa3256Schristos AslError (ASL_ERROR, ASL_MSG_NAMEPATH_NOT_EXIST, Op, 998*7efa3256Schristos Arg->Asl.ExternalName); 999*7efa3256Schristos } 1000*7efa3256Schristos 1001*7efa3256Schristos #if 0 1002*7efa3256Schristos /* 1003*7efa3256Schristos * NOTE: Removed 10/2018 to enhance compiler error reporting. No 1004*7efa3256Schristos * regressions seen. 1005*7efa3256Schristos */ 100628c506b8Sjruoho /* 100728c506b8Sjruoho * The name was not found, go ahead and create it. 100828c506b8Sjruoho * This prevents more errors later. 100928c506b8Sjruoho */ 101028c506b8Sjruoho Status = AcpiNsLookup (WalkState->ScopeInfo, Path, 1011*7efa3256Schristos ACPI_TYPE_ANY, ACPI_IMODE_LOAD_PASS1, 1012*7efa3256Schristos ACPI_NS_NO_UPSEARCH, WalkState, &Node); 1013*7efa3256Schristos #endif 1014*7efa3256Schristos return (Status); 1015*7efa3256Schristos /* Removed: return (AE_OK)*/ 101628c506b8Sjruoho } 101728c506b8Sjruoho 101828c506b8Sjruoho AslCoreSubsystemError (Op, Status, 101928c506b8Sjruoho "Failure from namespace lookup", FALSE); 102028c506b8Sjruoho return (AE_OK); 102128c506b8Sjruoho } 102228c506b8Sjruoho 102328c506b8Sjruoho /* Save the target node within the alias node */ 102428c506b8Sjruoho 102528c506b8Sjruoho Node->Object = ACPI_CAST_PTR (ACPI_OPERAND_OBJECT, TargetNode); 102628c506b8Sjruoho } 102728c506b8Sjruoho 102828c506b8Sjruoho return (AE_OK); 102928c506b8Sjruoho } 103028c506b8Sjruoho 103128c506b8Sjruoho 103228c506b8Sjruoho /******************************************************************************* 103328c506b8Sjruoho * 103428c506b8Sjruoho * FUNCTION: LdCommonNamespaceEnd 103528c506b8Sjruoho * 103628c506b8Sjruoho * PARAMETERS: ASL_WALK_CALLBACK 103728c506b8Sjruoho * 103828c506b8Sjruoho * RETURN: Status 103928c506b8Sjruoho * 104028c506b8Sjruoho * DESCRIPTION: Ascending callback used during the loading of the namespace, 104128c506b8Sjruoho * We only need to worry about managing the scope stack here. 104228c506b8Sjruoho * 104328c506b8Sjruoho ******************************************************************************/ 104428c506b8Sjruoho 104528c506b8Sjruoho static ACPI_STATUS 104628c506b8Sjruoho LdCommonNamespaceEnd ( 104728c506b8Sjruoho ACPI_PARSE_OBJECT *Op, 104828c506b8Sjruoho UINT32 Level, 104928c506b8Sjruoho void *Context) 105028c506b8Sjruoho { 105128c506b8Sjruoho ACPI_WALK_STATE *WalkState = (ACPI_WALK_STATE *) Context; 105228c506b8Sjruoho ACPI_OBJECT_TYPE ObjectType; 105328c506b8Sjruoho BOOLEAN ForceNewScope = FALSE; 105428c506b8Sjruoho 105528c506b8Sjruoho 105628c506b8Sjruoho ACPI_FUNCTION_NAME (LdCommonNamespaceEnd); 105728c506b8Sjruoho 105828c506b8Sjruoho 105928c506b8Sjruoho /* We are only interested in opcodes that have an associated name */ 106028c506b8Sjruoho 106128c506b8Sjruoho if (!Op->Asl.Namepath) 106228c506b8Sjruoho { 106328c506b8Sjruoho return (AE_OK); 106428c506b8Sjruoho } 106528c506b8Sjruoho 106628c506b8Sjruoho /* Get the type to determine if we should pop the scope */ 106728c506b8Sjruoho 106828c506b8Sjruoho if ((Op->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG) && 1069ae01dbf5Schristos (Op->Asl.CompileFlags == OP_IS_RESOURCE_DESC)) 107028c506b8Sjruoho { 107128c506b8Sjruoho /* TBD: Merge into AcpiDsMapNamedOpcodeToDataType */ 107228c506b8Sjruoho 107328c506b8Sjruoho ObjectType = ACPI_TYPE_LOCAL_RESOURCE; 107428c506b8Sjruoho } 107528c506b8Sjruoho else 107628c506b8Sjruoho { 107728c506b8Sjruoho ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode); 107828c506b8Sjruoho } 107928c506b8Sjruoho 108028c506b8Sjruoho /* Pop scope that was pushed for Resource Templates */ 108128c506b8Sjruoho 108228c506b8Sjruoho if (Op->Asl.ParseOpcode == PARSEOP_NAME) 108328c506b8Sjruoho { 1084ae01dbf5Schristos if (Op->Asl.CompileFlags & OP_IS_RESOURCE_DESC) 108528c506b8Sjruoho { 108628c506b8Sjruoho ForceNewScope = TRUE; 108728c506b8Sjruoho } 108828c506b8Sjruoho } 108928c506b8Sjruoho 109028c506b8Sjruoho /* Pop the scope stack */ 109128c506b8Sjruoho 109228c506b8Sjruoho if (ForceNewScope || AcpiNsOpensScope (ObjectType)) 109328c506b8Sjruoho { 109428c506b8Sjruoho ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, 109528c506b8Sjruoho "(%s): Popping scope for Op [%s] %p\n", 109628c506b8Sjruoho AcpiUtGetTypeName (ObjectType), Op->Asl.ParseOpName, Op)); 109728c506b8Sjruoho 109828c506b8Sjruoho (void) AcpiDsScopeStackPop (WalkState); 109928c506b8Sjruoho } 110028c506b8Sjruoho 110128c506b8Sjruoho return (AE_OK); 110228c506b8Sjruoho } 1103