128c506b8Sjruoho /****************************************************************************** 228c506b8Sjruoho * 328c506b8Sjruoho * Module Name: dswload - Dispatcher namespace load callbacks 428c506b8Sjruoho * 528c506b8Sjruoho *****************************************************************************/ 628c506b8Sjruoho 7124f4c82Sjruoho /* 85b948c02Schristos * Copyright (C) 2000 - 2019, 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 ( 59*7ab6b89bSchristos UINT32 AmlType, 6028c506b8Sjruoho ACPI_PARSE_OBJECT *Op, 6128c506b8Sjruoho ACPI_WALK_STATE *WalkState); 6228c506b8Sjruoho 6328c506b8Sjruoho static ACPI_STATUS 6428c506b8Sjruoho LdLoadResourceElements ( 6528c506b8Sjruoho ACPI_PARSE_OBJECT *Op, 6628c506b8Sjruoho ACPI_WALK_STATE *WalkState); 6728c506b8Sjruoho 6828c506b8Sjruoho static ACPI_STATUS 6928c506b8Sjruoho LdNamespace1Begin ( 7028c506b8Sjruoho ACPI_PARSE_OBJECT *Op, 7128c506b8Sjruoho UINT32 Level, 7228c506b8Sjruoho void *Context); 7328c506b8Sjruoho 7428c506b8Sjruoho static ACPI_STATUS 7528c506b8Sjruoho LdNamespace2Begin ( 7628c506b8Sjruoho ACPI_PARSE_OBJECT *Op, 7728c506b8Sjruoho UINT32 Level, 7828c506b8Sjruoho void *Context); 7928c506b8Sjruoho 8028c506b8Sjruoho static ACPI_STATUS 8128c506b8Sjruoho LdCommonNamespaceEnd ( 8228c506b8Sjruoho ACPI_PARSE_OBJECT *Op, 8328c506b8Sjruoho UINT32 Level, 8428c506b8Sjruoho void *Context); 8528c506b8Sjruoho 86*7ab6b89bSchristos static void 87*7ab6b89bSchristos LdCheckSpecialNames ( 88*7ab6b89bSchristos ACPI_NAMESPACE_NODE *Node, 89*7ab6b89bSchristos ACPI_PARSE_OBJECT *Op); 9028c506b8Sjruoho 9128c506b8Sjruoho /******************************************************************************* 9228c506b8Sjruoho * 9328c506b8Sjruoho * FUNCTION: LdLoadNamespace 9428c506b8Sjruoho * 9528c506b8Sjruoho * PARAMETERS: RootOp - Root of the parse tree 9628c506b8Sjruoho * 9728c506b8Sjruoho * RETURN: Status 9828c506b8Sjruoho * 9928c506b8Sjruoho * DESCRIPTION: Perform a walk of the parse tree that in turn loads all of the 10028c506b8Sjruoho * named ASL/AML objects into the namespace. The namespace is 10128c506b8Sjruoho * constructed in order to resolve named references and references 10228c506b8Sjruoho * to named fields within resource templates/descriptors. 10328c506b8Sjruoho * 10428c506b8Sjruoho ******************************************************************************/ 10528c506b8Sjruoho 10628c506b8Sjruoho ACPI_STATUS 10728c506b8Sjruoho LdLoadNamespace ( 10828c506b8Sjruoho ACPI_PARSE_OBJECT *RootOp) 10928c506b8Sjruoho { 11028c506b8Sjruoho ACPI_WALK_STATE *WalkState; 11128c506b8Sjruoho 11228c506b8Sjruoho 11328c506b8Sjruoho /* Create a new walk state */ 11428c506b8Sjruoho 11528c506b8Sjruoho WalkState = AcpiDsCreateWalkState (0, NULL, NULL, NULL); 11628c506b8Sjruoho if (!WalkState) 11728c506b8Sjruoho { 118ff4a156dSchristos return (AE_NO_MEMORY); 11928c506b8Sjruoho } 12028c506b8Sjruoho 12128c506b8Sjruoho /* Walk the entire parse tree, first pass */ 12228c506b8Sjruoho 12328c506b8Sjruoho TrWalkParseTree (RootOp, ASL_WALK_VISIT_TWICE, LdNamespace1Begin, 12428c506b8Sjruoho LdCommonNamespaceEnd, WalkState); 12528c506b8Sjruoho 12628c506b8Sjruoho /* Second pass to handle forward references */ 12728c506b8Sjruoho 12828c506b8Sjruoho TrWalkParseTree (RootOp, ASL_WALK_VISIT_TWICE, LdNamespace2Begin, 12928c506b8Sjruoho LdCommonNamespaceEnd, WalkState); 13028c506b8Sjruoho 13128c506b8Sjruoho /* Dump the namespace if debug is enabled */ 13228c506b8Sjruoho 133a147b75fSchristos if (AcpiDbgLevel & ACPI_LV_TABLES) 134a147b75fSchristos { 13528c506b8Sjruoho AcpiNsDumpTables (ACPI_NS_ALL, ACPI_UINT32_MAX); 136a147b75fSchristos } 137a147b75fSchristos 138414ef032Schristos ACPI_FREE (WalkState); 139ff4a156dSchristos return (AE_OK); 14028c506b8Sjruoho } 14128c506b8Sjruoho 14228c506b8Sjruoho 14328c506b8Sjruoho /******************************************************************************* 14428c506b8Sjruoho * 14528c506b8Sjruoho * FUNCTION: LdLoadFieldElements 14628c506b8Sjruoho * 147*7ab6b89bSchristos * PARAMETERS: AmlType - Type to search 148*7ab6b89bSchristos * Op - Parent node (Field) 14928c506b8Sjruoho * WalkState - Current walk state 15028c506b8Sjruoho * 15128c506b8Sjruoho * RETURN: Status 15228c506b8Sjruoho * 15328c506b8Sjruoho * DESCRIPTION: Enter the named elements of the field (children of the parent) 15428c506b8Sjruoho * into the namespace. 15528c506b8Sjruoho * 15628c506b8Sjruoho ******************************************************************************/ 15728c506b8Sjruoho 15828c506b8Sjruoho static ACPI_STATUS 15928c506b8Sjruoho LdLoadFieldElements ( 160*7ab6b89bSchristos UINT32 AmlType, 16128c506b8Sjruoho ACPI_PARSE_OBJECT *Op, 16228c506b8Sjruoho ACPI_WALK_STATE *WalkState) 16328c506b8Sjruoho { 16428c506b8Sjruoho ACPI_PARSE_OBJECT *Child = NULL; 165*7ab6b89bSchristos ACPI_PARSE_OBJECT *SourceRegion; 16628c506b8Sjruoho ACPI_NAMESPACE_NODE *Node; 16728c506b8Sjruoho ACPI_STATUS Status; 16828c506b8Sjruoho 16928c506b8Sjruoho 170*7ab6b89bSchristos SourceRegion = UtGetArg (Op, 0); 171*7ab6b89bSchristos if (SourceRegion) 172*7ab6b89bSchristos { 173*7ab6b89bSchristos Status = AcpiNsLookup (WalkState->ScopeInfo, 174*7ab6b89bSchristos SourceRegion->Asl.Value.String, 175*7ab6b89bSchristos AmlType, ACPI_IMODE_EXECUTE, 176*7ab6b89bSchristos ACPI_NS_DONT_OPEN_SCOPE, NULL, &Node); 177*7ab6b89bSchristos if (Status == AE_NOT_FOUND) 178*7ab6b89bSchristos { 179*7ab6b89bSchristos /* 180*7ab6b89bSchristos * If the named object is not found, it means that it is either a 181*7ab6b89bSchristos * forward reference or the named object does not exist. 182*7ab6b89bSchristos */ 183*7ab6b89bSchristos SourceRegion->Asl.CompileFlags |= OP_NOT_FOUND_DURING_LOAD; 184*7ab6b89bSchristos } 185*7ab6b89bSchristos } 186*7ab6b89bSchristos 18728c506b8Sjruoho /* Get the first named field element */ 18828c506b8Sjruoho 18928c506b8Sjruoho switch (Op->Asl.AmlOpcode) 19028c506b8Sjruoho { 19128c506b8Sjruoho case AML_BANK_FIELD_OP: 19228c506b8Sjruoho 19328c506b8Sjruoho Child = UtGetArg (Op, 6); 19428c506b8Sjruoho break; 19528c506b8Sjruoho 19628c506b8Sjruoho case AML_INDEX_FIELD_OP: 19728c506b8Sjruoho 19828c506b8Sjruoho Child = UtGetArg (Op, 5); 19928c506b8Sjruoho break; 20028c506b8Sjruoho 20128c506b8Sjruoho case AML_FIELD_OP: 20228c506b8Sjruoho 20328c506b8Sjruoho Child = UtGetArg (Op, 4); 20428c506b8Sjruoho break; 20528c506b8Sjruoho 20628c506b8Sjruoho default: 207ff4a156dSchristos 20828c506b8Sjruoho /* No other opcodes should arrive here */ 209ff4a156dSchristos 21028c506b8Sjruoho return (AE_BAD_PARAMETER); 21128c506b8Sjruoho } 21228c506b8Sjruoho 21328c506b8Sjruoho /* Enter all elements into the namespace */ 21428c506b8Sjruoho 21528c506b8Sjruoho while (Child) 21628c506b8Sjruoho { 21728c506b8Sjruoho switch (Child->Asl.AmlOpcode) 21828c506b8Sjruoho { 21928c506b8Sjruoho case AML_INT_RESERVEDFIELD_OP: 22028c506b8Sjruoho case AML_INT_ACCESSFIELD_OP: 221ff4a156dSchristos case AML_INT_CONNECTION_OP: 22228c506b8Sjruoho break; 22328c506b8Sjruoho 22428c506b8Sjruoho default: 22528c506b8Sjruoho 22628c506b8Sjruoho Status = AcpiNsLookup (WalkState->ScopeInfo, 22728c506b8Sjruoho Child->Asl.Value.String, 22828c506b8Sjruoho ACPI_TYPE_LOCAL_REGION_FIELD, 22928c506b8Sjruoho ACPI_IMODE_LOAD_PASS1, 23028c506b8Sjruoho ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE | 23181bd9c9cSchristos ACPI_NS_ERROR_IF_FOUND, NULL, &Node); 23228c506b8Sjruoho if (ACPI_FAILURE (Status)) 23328c506b8Sjruoho { 23428c506b8Sjruoho if (Status != AE_ALREADY_EXISTS) 23528c506b8Sjruoho { 23628c506b8Sjruoho AslError (ASL_ERROR, ASL_MSG_CORE_EXCEPTION, Child, 23728c506b8Sjruoho Child->Asl.Value.String); 23828c506b8Sjruoho return (Status); 23928c506b8Sjruoho } 240ae01dbf5Schristos else if (Status == AE_ALREADY_EXISTS && 241a147b75fSchristos (Node->Flags & ANOBJ_IS_EXTERNAL)) 242ae01dbf5Schristos { 243ae01dbf5Schristos Node->Type = (UINT8) ACPI_TYPE_LOCAL_REGION_FIELD; 2445b948c02Schristos Node->Flags &= ~ANOBJ_IS_EXTERNAL; 245ae01dbf5Schristos } 246ae01dbf5Schristos else 247ae01dbf5Schristos { 24828c506b8Sjruoho /* 24928c506b8Sjruoho * The name already exists in this scope 25028c506b8Sjruoho * But continue processing the elements 25128c506b8Sjruoho */ 2525b948c02Schristos AslDualParseOpError (ASL_WARNING, ASL_MSG_NAME_EXISTS, Child, 2535b948c02Schristos Child->Asl.Value.String, ASL_MSG_FOUND_HERE, Node->Op, 25425666a51Schristos Node->Op->Asl.ExternalName); 25528c506b8Sjruoho } 256ae01dbf5Schristos } 25728c506b8Sjruoho else 25828c506b8Sjruoho { 25928c506b8Sjruoho Child->Asl.Node = Node; 26028c506b8Sjruoho Node->Op = Child; 26128c506b8Sjruoho } 26228c506b8Sjruoho break; 26328c506b8Sjruoho } 264ff4a156dSchristos 26528c506b8Sjruoho Child = Child->Asl.Next; 26628c506b8Sjruoho } 267ff4a156dSchristos 26828c506b8Sjruoho return (AE_OK); 26928c506b8Sjruoho } 27028c506b8Sjruoho 27128c506b8Sjruoho 27228c506b8Sjruoho /******************************************************************************* 27328c506b8Sjruoho * 27428c506b8Sjruoho * FUNCTION: LdLoadResourceElements 27528c506b8Sjruoho * 27628c506b8Sjruoho * PARAMETERS: Op - Parent node (Resource Descriptor) 27728c506b8Sjruoho * WalkState - Current walk state 27828c506b8Sjruoho * 27928c506b8Sjruoho * RETURN: Status 28028c506b8Sjruoho * 28128c506b8Sjruoho * DESCRIPTION: Enter the named elements of the resource descriptor (children 28228c506b8Sjruoho * of the parent) into the namespace. 28328c506b8Sjruoho * 28428c506b8Sjruoho * NOTE: In the real AML namespace, these named elements never exist. But 28528c506b8Sjruoho * we simply use the namespace here as a symbol table so we can look 28628c506b8Sjruoho * them up as they are referenced. 28728c506b8Sjruoho * 28828c506b8Sjruoho ******************************************************************************/ 28928c506b8Sjruoho 29028c506b8Sjruoho static ACPI_STATUS 29128c506b8Sjruoho LdLoadResourceElements ( 29228c506b8Sjruoho ACPI_PARSE_OBJECT *Op, 29328c506b8Sjruoho ACPI_WALK_STATE *WalkState) 29428c506b8Sjruoho { 29528c506b8Sjruoho ACPI_PARSE_OBJECT *InitializerOp = NULL; 29628c506b8Sjruoho ACPI_NAMESPACE_NODE *Node; 29728c506b8Sjruoho ACPI_STATUS Status; 29828c506b8Sjruoho 29928c506b8Sjruoho 30028c506b8Sjruoho /* 30128c506b8Sjruoho * Enter the resource name into the namespace. Name must not already exist. 30228c506b8Sjruoho * This opens a scope, so later field names are guaranteed to be new/unique. 30328c506b8Sjruoho */ 30428c506b8Sjruoho Status = AcpiNsLookup (WalkState->ScopeInfo, Op->Asl.Namepath, 30528c506b8Sjruoho ACPI_TYPE_LOCAL_RESOURCE, ACPI_IMODE_LOAD_PASS1, 30628c506b8Sjruoho ACPI_NS_NO_UPSEARCH | ACPI_NS_ERROR_IF_FOUND, 30728c506b8Sjruoho WalkState, &Node); 30828c506b8Sjruoho if (ACPI_FAILURE (Status)) 30928c506b8Sjruoho { 31028c506b8Sjruoho if (Status == AE_ALREADY_EXISTS) 31128c506b8Sjruoho { 31228c506b8Sjruoho /* Actual node causing the error was saved in ParentMethod */ 31328c506b8Sjruoho 31425666a51Schristos AslDualParseOpError (ASL_ERROR, ASL_MSG_NAME_EXISTS, 31525666a51Schristos (ACPI_PARSE_OBJECT *) Op->Asl.ParentMethod, 31625666a51Schristos Op->Asl.Namepath, ASL_MSG_FOUND_HERE, Node->Op, 31725666a51Schristos Node->Op->Asl.ExternalName); 31828c506b8Sjruoho return (AE_OK); 31928c506b8Sjruoho } 32028c506b8Sjruoho return (Status); 32128c506b8Sjruoho } 32228c506b8Sjruoho 32328c506b8Sjruoho Node->Value = (UINT32) Op->Asl.Value.Integer; 32428c506b8Sjruoho Node->Op = Op; 32528c506b8Sjruoho Op->Asl.Node = Node; 32628c506b8Sjruoho 32728c506b8Sjruoho /* 32828c506b8Sjruoho * Now enter the predefined fields, for easy lookup when referenced 32928c506b8Sjruoho * by the source ASL 33028c506b8Sjruoho */ 33128c506b8Sjruoho InitializerOp = ASL_GET_CHILD_NODE (Op); 33228c506b8Sjruoho while (InitializerOp) 33328c506b8Sjruoho { 33428c506b8Sjruoho if (InitializerOp->Asl.ExternalName) 33528c506b8Sjruoho { 33628c506b8Sjruoho Status = AcpiNsLookup (WalkState->ScopeInfo, 33728c506b8Sjruoho InitializerOp->Asl.ExternalName, 3387efa3256Schristos ACPI_TYPE_LOCAL_RESOURCE_FIELD, ACPI_IMODE_LOAD_PASS1, 3397efa3256Schristos ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE, NULL, &Node); 34028c506b8Sjruoho if (ACPI_FAILURE (Status)) 34128c506b8Sjruoho { 34228c506b8Sjruoho return (Status); 34328c506b8Sjruoho } 34428c506b8Sjruoho 34528c506b8Sjruoho /* 346ff4a156dSchristos * Store the field offset and length in the namespace node 347ff4a156dSchristos * so it can be used when the field is referenced 34828c506b8Sjruoho */ 349ff4a156dSchristos Node->Value = InitializerOp->Asl.Value.Tag.BitOffset; 350ff4a156dSchristos Node->Length = InitializerOp->Asl.Value.Tag.BitLength; 35128c506b8Sjruoho InitializerOp->Asl.Node = Node; 35228c506b8Sjruoho Node->Op = InitializerOp; 35328c506b8Sjruoho } 354ff4a156dSchristos 35528c506b8Sjruoho InitializerOp = ASL_GET_PEER_NODE (InitializerOp); 35628c506b8Sjruoho } 35728c506b8Sjruoho 35828c506b8Sjruoho return (AE_OK); 35928c506b8Sjruoho } 36028c506b8Sjruoho 36128c506b8Sjruoho 36228c506b8Sjruoho /******************************************************************************* 36328c506b8Sjruoho * 36428c506b8Sjruoho * FUNCTION: LdNamespace1Begin 36528c506b8Sjruoho * 36628c506b8Sjruoho * PARAMETERS: ASL_WALK_CALLBACK 36728c506b8Sjruoho * 36828c506b8Sjruoho * RETURN: Status 36928c506b8Sjruoho * 37028c506b8Sjruoho * DESCRIPTION: Descending callback used during the parse tree walk. If this 37128c506b8Sjruoho * is a named AML opcode, enter into the namespace 37228c506b8Sjruoho * 37328c506b8Sjruoho ******************************************************************************/ 37428c506b8Sjruoho 37528c506b8Sjruoho static ACPI_STATUS 37628c506b8Sjruoho LdNamespace1Begin ( 37728c506b8Sjruoho ACPI_PARSE_OBJECT *Op, 37828c506b8Sjruoho UINT32 Level, 37928c506b8Sjruoho void *Context) 38028c506b8Sjruoho { 38128c506b8Sjruoho ACPI_WALK_STATE *WalkState = (ACPI_WALK_STATE *) Context; 38228c506b8Sjruoho ACPI_NAMESPACE_NODE *Node; 38381bd9c9cSchristos ACPI_PARSE_OBJECT *MethodOp; 38428c506b8Sjruoho ACPI_STATUS Status; 38528c506b8Sjruoho ACPI_OBJECT_TYPE ObjectType; 38628c506b8Sjruoho ACPI_OBJECT_TYPE ActualObjectType = ACPI_TYPE_ANY; 38728c506b8Sjruoho char *Path; 38828c506b8Sjruoho UINT32 Flags = ACPI_NS_NO_UPSEARCH; 38928c506b8Sjruoho ACPI_PARSE_OBJECT *Arg; 39028c506b8Sjruoho UINT32 i; 39128c506b8Sjruoho BOOLEAN ForceNewScope = FALSE; 392a40a9998Schristos const ACPI_OPCODE_INFO *OpInfo; 393a40a9998Schristos ACPI_PARSE_OBJECT *ParentOp; 39428c506b8Sjruoho 39528c506b8Sjruoho 39628c506b8Sjruoho ACPI_FUNCTION_NAME (LdNamespace1Begin); 397a40a9998Schristos 398a40a9998Schristos 39928c506b8Sjruoho ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Op %p [%s]\n", 40028c506b8Sjruoho Op, Op->Asl.ParseOpName)); 40128c506b8Sjruoho 40228c506b8Sjruoho /* 40328c506b8Sjruoho * We are only interested in opcodes that have an associated name 40428c506b8Sjruoho * (or multiple names) 40528c506b8Sjruoho */ 40628c506b8Sjruoho switch (Op->Asl.AmlOpcode) 40728c506b8Sjruoho { 40828c506b8Sjruoho case AML_INDEX_FIELD_OP: 409*7ab6b89bSchristos 410*7ab6b89bSchristos Status = LdLoadFieldElements (ACPI_TYPE_LOCAL_REGION_FIELD, Op, WalkState); 411*7ab6b89bSchristos return (Status); 412*7ab6b89bSchristos 413*7ab6b89bSchristos case AML_BANK_FIELD_OP: 41428c506b8Sjruoho case AML_FIELD_OP: 41528c506b8Sjruoho 416*7ab6b89bSchristos Status = LdLoadFieldElements (ACPI_TYPE_REGION, Op, WalkState); 417*7ab6b89bSchristos return (Status); 41828c506b8Sjruoho 419414ef032Schristos case AML_INT_CONNECTION_OP: 420414ef032Schristos 421414ef032Schristos 422414ef032Schristos if (Op->Asl.Child->Asl.AmlOpcode != AML_INT_NAMEPATH_OP) 423414ef032Schristos { 424414ef032Schristos break; 425414ef032Schristos } 426414ef032Schristos Arg = Op->Asl.Child; 427414ef032Schristos 428414ef032Schristos Status = AcpiNsLookup (WalkState->ScopeInfo, Arg->Asl.ExternalName, 429414ef032Schristos ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT, 430414ef032Schristos WalkState, &Node); 431414ef032Schristos if (ACPI_FAILURE (Status)) 432414ef032Schristos { 433414ef032Schristos break; 434414ef032Schristos } 435414ef032Schristos 436414ef032Schristos if (Node->Type == ACPI_TYPE_BUFFER) 437414ef032Schristos { 438414ef032Schristos Arg->Asl.Node = Node; 439414ef032Schristos 440414ef032Schristos Arg = Node->Op->Asl.Child; /* Get namepath */ 441414ef032Schristos Arg = Arg->Asl.Next; /* Get actual buffer */ 442414ef032Schristos Arg = Arg->Asl.Child; /* Buffer length */ 443414ef032Schristos Arg = Arg->Asl.Next; /* RAW_DATA buffer */ 444414ef032Schristos } 445414ef032Schristos break; 446414ef032Schristos 44728c506b8Sjruoho default: 44828c506b8Sjruoho 44928c506b8Sjruoho /* All other opcodes go below */ 450ff4a156dSchristos 45128c506b8Sjruoho break; 45228c506b8Sjruoho } 45328c506b8Sjruoho 45428c506b8Sjruoho /* Check if this object has already been installed in the namespace */ 45528c506b8Sjruoho 45628c506b8Sjruoho if (Op->Asl.Node) 45728c506b8Sjruoho { 45828c506b8Sjruoho return (AE_OK); 45928c506b8Sjruoho } 46028c506b8Sjruoho 461a40a9998Schristos /* Check for a possible illegal forward reference */ 462a40a9998Schristos 463a40a9998Schristos if ((Op->Asl.ParseOpcode == PARSEOP_NAMESEG) || 464a40a9998Schristos (Op->Asl.ParseOpcode == PARSEOP_NAMESTRING)) 465a40a9998Schristos { 466a40a9998Schristos /* 467a40a9998Schristos * Op->Asl.Namepath will be NULL for these opcodes. 468a40a9998Schristos * These opcodes are guaranteed to have a parent. 469a40a9998Schristos * Examine the parent opcode. 470a40a9998Schristos */ 471a40a9998Schristos Status = AE_OK; 472a40a9998Schristos ParentOp = Op->Asl.Parent; 473a40a9998Schristos OpInfo = AcpiPsGetOpcodeInfo (ParentOp->Asl.AmlOpcode); 474a40a9998Schristos 475a40a9998Schristos /* 476a40a9998Schristos * Exclude all operators that actually declare a new name: 477a40a9998Schristos * Name (ABCD, 1) -> Ignore (AML_CLASS_NAMED_OBJECT) 478a40a9998Schristos * We only want references to named objects: 479a40a9998Schristos * Store (2, WXYZ) -> Attempt to resolve the name 480a40a9998Schristos */ 481*7ab6b89bSchristos if (OpInfo->Class == AML_CLASS_NAMED_OBJECT) 482a40a9998Schristos { 483a40a9998Schristos return (AE_OK); 484a40a9998Schristos } 485a40a9998Schristos 486a40a9998Schristos /* 487a40a9998Schristos * Check if the referenced object exists at this point during 488a40a9998Schristos * the load: 489a40a9998Schristos * 1) If it exists, then this cannot be a forward reference. 490a40a9998Schristos * 2) If it does not exist, it could be a forward reference or 491a40a9998Schristos * it truly does not exist (and no external declaration). 492a40a9998Schristos */ 493a40a9998Schristos Status = AcpiNsLookup (WalkState->ScopeInfo, 494a40a9998Schristos Op->Asl.Value.Name, ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE, 495a40a9998Schristos ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE, 496a40a9998Schristos WalkState, &Node); 497a40a9998Schristos if (Status == AE_NOT_FOUND) 498a40a9998Schristos { 499a40a9998Schristos /* 5005b948c02Schristos * This is either a forward reference or the object truly 501a40a9998Schristos * does not exist. The two cases can only be differentiated 502a40a9998Schristos * during the cross-reference stage later. Mark the Op/Name 503a40a9998Schristos * as not-found for now to indicate the need for further 504a40a9998Schristos * processing. 505a40a9998Schristos * 506a40a9998Schristos * Special case: Allow forward references from elements of 507a40a9998Schristos * Package objects. This provides compatibility with other 508a40a9998Schristos * ACPI implementations. To correctly implement this, the 509a40a9998Schristos * ACPICA table load defers package resolution until the entire 510a40a9998Schristos * namespace has been loaded. 511a40a9998Schristos */ 512a40a9998Schristos if ((ParentOp->Asl.ParseOpcode != PARSEOP_PACKAGE) && 513a40a9998Schristos (ParentOp->Asl.ParseOpcode != PARSEOP_VAR_PACKAGE)) 514a40a9998Schristos { 515a40a9998Schristos Op->Asl.CompileFlags |= OP_NOT_FOUND_DURING_LOAD; 516a40a9998Schristos } 517a40a9998Schristos 518a40a9998Schristos return (AE_OK); 519a40a9998Schristos } 520a40a9998Schristos 521a40a9998Schristos return (Status); 522a40a9998Schristos } 523a40a9998Schristos 52428c506b8Sjruoho Path = Op->Asl.Namepath; 52528c506b8Sjruoho if (!Path) 52628c506b8Sjruoho { 52728c506b8Sjruoho return (AE_OK); 52828c506b8Sjruoho } 52928c506b8Sjruoho 53028c506b8Sjruoho /* Map the raw opcode into an internal object type */ 53128c506b8Sjruoho 53228c506b8Sjruoho switch (Op->Asl.ParseOpcode) 53328c506b8Sjruoho { 53428c506b8Sjruoho case PARSEOP_NAME: 53528c506b8Sjruoho 53628c506b8Sjruoho Arg = Op->Asl.Child; /* Get the NameSeg/NameString node */ 53728c506b8Sjruoho Arg = Arg->Asl.Next; /* First peer is the object to be associated with the name */ 53828c506b8Sjruoho 53928c506b8Sjruoho /* 54028c506b8Sjruoho * If this name refers to a ResourceTemplate, we will need to open 54128c506b8Sjruoho * a new scope so that the resource subfield names can be entered into 54228c506b8Sjruoho * the namespace underneath this name 54328c506b8Sjruoho */ 544ae01dbf5Schristos if (Op->Asl.CompileFlags & OP_IS_RESOURCE_DESC) 54528c506b8Sjruoho { 54628c506b8Sjruoho ForceNewScope = TRUE; 54728c506b8Sjruoho } 54828c506b8Sjruoho 54928c506b8Sjruoho /* Get the data type associated with the named object, not the name itself */ 55028c506b8Sjruoho 55128c506b8Sjruoho /* Log2 loop to convert from Btype (binary) to Etype (encoded) */ 55228c506b8Sjruoho 55328c506b8Sjruoho ObjectType = 1; 55428c506b8Sjruoho for (i = 1; i < Arg->Asl.AcpiBtype; i *= 2) 55528c506b8Sjruoho { 55628c506b8Sjruoho ObjectType++; 55728c506b8Sjruoho } 55828c506b8Sjruoho break; 55928c506b8Sjruoho 56028c506b8Sjruoho case PARSEOP_EXTERNAL: 56128c506b8Sjruoho /* 56228c506b8Sjruoho * "External" simply enters a name and type into the namespace. 56328c506b8Sjruoho * We must be careful to not open a new scope, however, no matter 56428c506b8Sjruoho * what type the external name refers to (e.g., a method) 56528c506b8Sjruoho * 56628c506b8Sjruoho * first child is name, next child is ObjectType 56728c506b8Sjruoho */ 56828c506b8Sjruoho ActualObjectType = (UINT8) Op->Asl.Child->Asl.Next->Asl.Value.Integer; 56928c506b8Sjruoho ObjectType = ACPI_TYPE_ANY; 57028c506b8Sjruoho 57128c506b8Sjruoho /* 57228c506b8Sjruoho * We will mark every new node along the path as "External". This 57328c506b8Sjruoho * allows some or all of the nodes to be created later in the ASL 57428c506b8Sjruoho * code. Handles cases like this: 57528c506b8Sjruoho * 57628c506b8Sjruoho * External (\_SB_.PCI0.ABCD, IntObj) 57728c506b8Sjruoho * Scope (_SB_) 57828c506b8Sjruoho * { 57928c506b8Sjruoho * Device (PCI0) 58028c506b8Sjruoho * { 58128c506b8Sjruoho * } 58228c506b8Sjruoho * } 58328c506b8Sjruoho * Method (X) 58428c506b8Sjruoho * { 58528c506b8Sjruoho * Store (\_SB_.PCI0.ABCD, Local0) 58628c506b8Sjruoho * } 58728c506b8Sjruoho */ 58828c506b8Sjruoho Flags |= ACPI_NS_EXTERNAL; 58928c506b8Sjruoho break; 59028c506b8Sjruoho 59128c506b8Sjruoho case PARSEOP_DEFAULT_ARG: 59228c506b8Sjruoho 593ae01dbf5Schristos if (Op->Asl.CompileFlags == OP_IS_RESOURCE_DESC) 59428c506b8Sjruoho { 59528c506b8Sjruoho Status = LdLoadResourceElements (Op, WalkState); 59628c506b8Sjruoho return_ACPI_STATUS (Status); 59728c506b8Sjruoho } 59828c506b8Sjruoho 59928c506b8Sjruoho ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode); 60028c506b8Sjruoho break; 60128c506b8Sjruoho 60228c506b8Sjruoho case PARSEOP_SCOPE: 60328c506b8Sjruoho /* 60428c506b8Sjruoho * The name referenced by Scope(Name) must already exist at this point. 60528c506b8Sjruoho * In other words, forward references for Scope() are not supported. 60628c506b8Sjruoho * The only real reason for this is that the MS interpreter cannot 60728c506b8Sjruoho * handle this case. Perhaps someday this case can go away. 60828c506b8Sjruoho */ 60928c506b8Sjruoho Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ACPI_TYPE_ANY, 6107efa3256Schristos ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT, WalkState, &Node); 61128c506b8Sjruoho if (ACPI_FAILURE (Status)) 61228c506b8Sjruoho { 61328c506b8Sjruoho if (Status == AE_NOT_FOUND) 61428c506b8Sjruoho { 61528c506b8Sjruoho /* The name was not found, go ahead and create it */ 61628c506b8Sjruoho 61728c506b8Sjruoho Status = AcpiNsLookup (WalkState->ScopeInfo, Path, 6187efa3256Schristos ACPI_TYPE_LOCAL_SCOPE, ACPI_IMODE_LOAD_PASS1, 6197efa3256Schristos Flags, WalkState, &Node); 620ff4a156dSchristos if (ACPI_FAILURE (Status)) 621ff4a156dSchristos { 622ff4a156dSchristos return_ACPI_STATUS (Status); 623ff4a156dSchristos } 62428c506b8Sjruoho 6257efa3256Schristos /* However, this is an error -- operand to Scope must exist */ 6267efa3256Schristos 6275b948c02Schristos if (strlen (Op->Asl.ExternalName) == ACPI_NAMESEG_SIZE) 6287efa3256Schristos { 62928c506b8Sjruoho AslError (ASL_ERROR, ASL_MSG_NOT_FOUND, Op, 63028c506b8Sjruoho Op->Asl.ExternalName); 6317efa3256Schristos } 6327efa3256Schristos else 6337efa3256Schristos { 6347efa3256Schristos AslError (ASL_ERROR, ASL_MSG_NAMEPATH_NOT_EXIST, Op, 63528c506b8Sjruoho Op->Asl.ExternalName); 6367efa3256Schristos } 6377efa3256Schristos 63828c506b8Sjruoho goto FinishNode; 63928c506b8Sjruoho } 64028c506b8Sjruoho 64128c506b8Sjruoho AslCoreSubsystemError (Op, Status, 64228c506b8Sjruoho "Failure from namespace lookup", FALSE); 64328c506b8Sjruoho 64428c506b8Sjruoho return_ACPI_STATUS (Status); 64528c506b8Sjruoho } 64681bd9c9cSchristos else /* Status AE_OK */ 64781bd9c9cSchristos { 64881bd9c9cSchristos /* 64981bd9c9cSchristos * Do not allow references to external scopes from the DSDT. 65081bd9c9cSchristos * This is because the DSDT is always loaded first, and the 65181bd9c9cSchristos * external reference cannot be resolved -- causing a runtime 65281bd9c9cSchristos * error because Scope() must be resolved immediately. 65381bd9c9cSchristos * 10/2015. 65481bd9c9cSchristos */ 65581bd9c9cSchristos if ((Node->Flags & ANOBJ_IS_EXTERNAL) && 6565b948c02Schristos (ACPI_COMPARE_NAMESEG (AslGbl_TableSignature, "DSDT"))) 65781bd9c9cSchristos { 65881bd9c9cSchristos /* However, allowed if the reference is within a method */ 65981bd9c9cSchristos 66081bd9c9cSchristos MethodOp = Op->Asl.Parent; 66181bd9c9cSchristos while (MethodOp && 66281bd9c9cSchristos (MethodOp->Asl.ParseOpcode != PARSEOP_METHOD)) 66381bd9c9cSchristos { 66481bd9c9cSchristos MethodOp = MethodOp->Asl.Parent; 66581bd9c9cSchristos } 66681bd9c9cSchristos 66781bd9c9cSchristos if (!MethodOp) 66881bd9c9cSchristos { 66981bd9c9cSchristos /* Not in a control method, error */ 67081bd9c9cSchristos 67181bd9c9cSchristos AslError (ASL_ERROR, ASL_MSG_CROSS_TABLE_SCOPE, Op, NULL); 67281bd9c9cSchristos } 67381bd9c9cSchristos } 67481bd9c9cSchristos } 67528c506b8Sjruoho 67628c506b8Sjruoho /* We found a node with this name, now check the type */ 67728c506b8Sjruoho 67828c506b8Sjruoho switch (Node->Type) 67928c506b8Sjruoho { 68028c506b8Sjruoho case ACPI_TYPE_LOCAL_SCOPE: 68128c506b8Sjruoho case ACPI_TYPE_DEVICE: 68228c506b8Sjruoho case ACPI_TYPE_POWER: 68328c506b8Sjruoho case ACPI_TYPE_PROCESSOR: 68428c506b8Sjruoho case ACPI_TYPE_THERMAL: 68528c506b8Sjruoho 68628c506b8Sjruoho /* These are acceptable types - they all open a new scope */ 68728c506b8Sjruoho break; 68828c506b8Sjruoho 68928c506b8Sjruoho case ACPI_TYPE_INTEGER: 69028c506b8Sjruoho case ACPI_TYPE_STRING: 69128c506b8Sjruoho case ACPI_TYPE_BUFFER: 69228c506b8Sjruoho /* 69328c506b8Sjruoho * These types we will allow, but we will change the type. 69428c506b8Sjruoho * This enables some existing code of the form: 69528c506b8Sjruoho * 69628c506b8Sjruoho * Name (DEB, 0) 69728c506b8Sjruoho * Scope (DEB) { ... } 69828c506b8Sjruoho * 69928c506b8Sjruoho * Which is used to workaround the fact that the MS interpreter 70028c506b8Sjruoho * does not allow Scope() forward references. 70128c506b8Sjruoho */ 7027efa3256Schristos snprintf (AslGbl_MsgBuffer, sizeof(AslGbl_MsgBuffer), "%s [%s], changing type to [Scope]", 70328c506b8Sjruoho Op->Asl.ExternalName, AcpiUtGetTypeName (Node->Type)); 7047efa3256Schristos AslError (ASL_REMARK, ASL_MSG_SCOPE_TYPE, Op, AslGbl_MsgBuffer); 70528c506b8Sjruoho 70628c506b8Sjruoho /* Switch the type to scope, open the new scope */ 70728c506b8Sjruoho 70828c506b8Sjruoho Node->Type = ACPI_TYPE_LOCAL_SCOPE; 70928c506b8Sjruoho Status = AcpiDsScopeStackPush (Node, ACPI_TYPE_LOCAL_SCOPE, 71028c506b8Sjruoho WalkState); 71128c506b8Sjruoho if (ACPI_FAILURE (Status)) 71228c506b8Sjruoho { 71328c506b8Sjruoho return_ACPI_STATUS (Status); 71428c506b8Sjruoho } 71528c506b8Sjruoho break; 71628c506b8Sjruoho 71728c506b8Sjruoho default: 71828c506b8Sjruoho 71928c506b8Sjruoho /* All other types are an error */ 72028c506b8Sjruoho 7217efa3256Schristos snprintf (AslGbl_MsgBuffer, sizeof(AslGbl_MsgBuffer), "%s [%s]", Op->Asl.ExternalName, 72228c506b8Sjruoho AcpiUtGetTypeName (Node->Type)); 7237efa3256Schristos AslError (ASL_ERROR, ASL_MSG_SCOPE_TYPE, Op, AslGbl_MsgBuffer); 72428c506b8Sjruoho 72528c506b8Sjruoho /* 72628c506b8Sjruoho * However, switch the type to be an actual scope so 72728c506b8Sjruoho * that compilation can continue without generating a whole 72828c506b8Sjruoho * cascade of additional errors. Open the new scope. 72928c506b8Sjruoho */ 73028c506b8Sjruoho Node->Type = ACPI_TYPE_LOCAL_SCOPE; 73128c506b8Sjruoho Status = AcpiDsScopeStackPush (Node, ACPI_TYPE_LOCAL_SCOPE, 73228c506b8Sjruoho WalkState); 73328c506b8Sjruoho if (ACPI_FAILURE (Status)) 73428c506b8Sjruoho { 73528c506b8Sjruoho return_ACPI_STATUS (Status); 73628c506b8Sjruoho } 73728c506b8Sjruoho break; 73828c506b8Sjruoho } 73928c506b8Sjruoho 74028c506b8Sjruoho Status = AE_OK; 74128c506b8Sjruoho goto FinishNode; 74228c506b8Sjruoho 74328c506b8Sjruoho default: 74428c506b8Sjruoho 74528c506b8Sjruoho ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode); 74628c506b8Sjruoho break; 74728c506b8Sjruoho } 74828c506b8Sjruoho 74928c506b8Sjruoho ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Loading name: %s, (%s)\n", 75028c506b8Sjruoho Op->Asl.ExternalName, AcpiUtGetTypeName (ObjectType))); 75128c506b8Sjruoho 75228c506b8Sjruoho /* The name must not already exist */ 75328c506b8Sjruoho 75428c506b8Sjruoho Flags |= ACPI_NS_ERROR_IF_FOUND; 75528c506b8Sjruoho 75628c506b8Sjruoho /* 7577efa3256Schristos * For opcodes that enter new names into the namespace, 7587efa3256Schristos * all prefix NameSegs must exist. 7597efa3256Schristos */ 7607efa3256Schristos WalkState->OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode); 7617efa3256Schristos if (((WalkState->OpInfo->Flags & AML_NAMED) || 7627efa3256Schristos (WalkState->OpInfo->Flags & AML_CREATE)) && 7637efa3256Schristos (Op->Asl.AmlOpcode != AML_EXTERNAL_OP)) 7647efa3256Schristos { 7657efa3256Schristos Flags |= ACPI_NS_PREFIX_MUST_EXIST; 7667efa3256Schristos } 7677efa3256Schristos 7687efa3256Schristos /* 76928c506b8Sjruoho * Enter the named type into the internal namespace. We enter the name 77028c506b8Sjruoho * as we go downward in the parse tree. Any necessary subobjects that 77128c506b8Sjruoho * involve arguments to the opcode must be created as we go back up the 77228c506b8Sjruoho * parse tree later. 77328c506b8Sjruoho */ 77428c506b8Sjruoho Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ObjectType, 77528c506b8Sjruoho ACPI_IMODE_LOAD_PASS1, Flags, WalkState, &Node); 77628c506b8Sjruoho if (ACPI_FAILURE (Status)) 77728c506b8Sjruoho { 77828c506b8Sjruoho if (Status == AE_ALREADY_EXISTS) 77928c506b8Sjruoho { 78028c506b8Sjruoho /* The name already exists in this scope */ 78128c506b8Sjruoho 78228c506b8Sjruoho if (Node->Type == ACPI_TYPE_LOCAL_SCOPE) 78328c506b8Sjruoho { 78428c506b8Sjruoho /* Allow multiple references to the same scope */ 78528c506b8Sjruoho 78628c506b8Sjruoho Node->Type = (UINT8) ObjectType; 78728c506b8Sjruoho Status = AE_OK; 78828c506b8Sjruoho } 78928c506b8Sjruoho else if ((Node->Flags & ANOBJ_IS_EXTERNAL) && 79028c506b8Sjruoho (Op->Asl.ParseOpcode != PARSEOP_EXTERNAL)) 79128c506b8Sjruoho { 79228c506b8Sjruoho /* 79328c506b8Sjruoho * Allow one create on an object or segment that was 794a147b75fSchristos * previously declared External 79528c506b8Sjruoho */ 79628c506b8Sjruoho Node->Flags &= ~ANOBJ_IS_EXTERNAL; 79728c506b8Sjruoho Node->Type = (UINT8) ObjectType; 79828c506b8Sjruoho 79928c506b8Sjruoho /* Just retyped a node, probably will need to open a scope */ 80028c506b8Sjruoho 80128c506b8Sjruoho if (AcpiNsOpensScope (ObjectType)) 80228c506b8Sjruoho { 80328c506b8Sjruoho Status = AcpiDsScopeStackPush (Node, ObjectType, WalkState); 80428c506b8Sjruoho if (ACPI_FAILURE (Status)) 80528c506b8Sjruoho { 80628c506b8Sjruoho return_ACPI_STATUS (Status); 80728c506b8Sjruoho } 80828c506b8Sjruoho } 80981bd9c9cSchristos 81081bd9c9cSchristos Status = AE_OK; 81181bd9c9cSchristos } 81281bd9c9cSchristos else if (!(Node->Flags & ANOBJ_IS_EXTERNAL) && 81381bd9c9cSchristos (Op->Asl.ParseOpcode == PARSEOP_EXTERNAL)) 81481bd9c9cSchristos { 81581bd9c9cSchristos /* 81681bd9c9cSchristos * Allow externals in same scope as the definition of the 81781bd9c9cSchristos * actual object. Similar to C. Allows multiple definition 818a147b75fSchristos * blocks that refer to each other in the same file. 81981bd9c9cSchristos */ 82028c506b8Sjruoho Status = AE_OK; 82128c506b8Sjruoho } 82249c2f1f4Schristos else if ((Node->Flags & ANOBJ_IS_EXTERNAL) && 82349c2f1f4Schristos (Op->Asl.ParseOpcode == PARSEOP_EXTERNAL) && 82449c2f1f4Schristos (ObjectType == ACPI_TYPE_ANY)) 82549c2f1f4Schristos { 826a147b75fSchristos /* Allow update of externals of unknown type. */ 82749c2f1f4Schristos 82849c2f1f4Schristos if (AcpiNsOpensScope (ActualObjectType)) 82949c2f1f4Schristos { 83049c2f1f4Schristos Node->Type = (UINT8) ActualObjectType; 83149c2f1f4Schristos Status = AE_OK; 83249c2f1f4Schristos } 83349c2f1f4Schristos else 83449c2f1f4Schristos { 8357efa3256Schristos sprintf (AslGbl_MsgBuffer, "%s [%s]", Op->Asl.ExternalName, 83649c2f1f4Schristos AcpiUtGetTypeName (Node->Type)); 8377efa3256Schristos AslError (ASL_ERROR, ASL_MSG_SCOPE_TYPE, Op, AslGbl_MsgBuffer); 83849c2f1f4Schristos return_ACPI_STATUS (AE_OK); 83949c2f1f4Schristos } 84049c2f1f4Schristos } 84128c506b8Sjruoho else 84228c506b8Sjruoho { 84328c506b8Sjruoho /* Valid error, object already exists */ 84428c506b8Sjruoho 84525666a51Schristos AslDualParseOpError (ASL_ERROR, ASL_MSG_NAME_EXISTS, Op, 84625666a51Schristos Op->Asl.ExternalName, ASL_MSG_FOUND_HERE, Node->Op, 84725666a51Schristos Node->Op->Asl.ExternalName); 84828c506b8Sjruoho return_ACPI_STATUS (AE_OK); 84928c506b8Sjruoho } 85028c506b8Sjruoho } 8517efa3256Schristos else if (AE_NOT_FOUND) 8527efa3256Schristos { 8537efa3256Schristos /* 8547efa3256Schristos * One or more prefix NameSegs of the NamePath do not exist 8557efa3256Schristos * (all of them must exist). Attempt to continue compilation 8567efa3256Schristos * by setting the current scope to the root. 8577efa3256Schristos */ 8587efa3256Schristos Node = AcpiGbl_RootNode; 8597efa3256Schristos Status = AE_OK; 8607efa3256Schristos } 86128c506b8Sjruoho else 86228c506b8Sjruoho { 8637efa3256Schristos /* Flag all other errors as coming from the ACPICA core */ 8647efa3256Schristos 86528c506b8Sjruoho AslCoreSubsystemError (Op, Status, 86628c506b8Sjruoho "Failure from namespace lookup", FALSE); 86728c506b8Sjruoho return_ACPI_STATUS (Status); 86828c506b8Sjruoho } 86928c506b8Sjruoho } 87028c506b8Sjruoho 871*7ab6b89bSchristos /* Check special names like _WAK and _PTS */ 872*7ab6b89bSchristos 873*7ab6b89bSchristos LdCheckSpecialNames (Node, Op); 874*7ab6b89bSchristos 87528c506b8Sjruoho if (ForceNewScope) 87628c506b8Sjruoho { 87728c506b8Sjruoho Status = AcpiDsScopeStackPush (Node, ObjectType, WalkState); 87828c506b8Sjruoho if (ACPI_FAILURE (Status)) 87928c506b8Sjruoho { 88028c506b8Sjruoho return_ACPI_STATUS (Status); 88128c506b8Sjruoho } 88228c506b8Sjruoho } 88328c506b8Sjruoho 88428c506b8Sjruoho FinishNode: 88528c506b8Sjruoho /* 88628c506b8Sjruoho * Point the parse node to the new namespace node, and point 88728c506b8Sjruoho * the Node back to the original Parse node 88828c506b8Sjruoho */ 88928c506b8Sjruoho Op->Asl.Node = Node; 89028c506b8Sjruoho Node->Op = Op; 89128c506b8Sjruoho 89228c506b8Sjruoho /* Set the actual data type if appropriate (EXTERNAL term only) */ 89328c506b8Sjruoho 89428c506b8Sjruoho if (ActualObjectType != ACPI_TYPE_ANY) 89528c506b8Sjruoho { 89628c506b8Sjruoho Node->Type = (UINT8) ActualObjectType; 89728c506b8Sjruoho Node->Value = ASL_EXTERNAL_METHOD; 89828c506b8Sjruoho } 89928c506b8Sjruoho 90028c506b8Sjruoho if (Op->Asl.ParseOpcode == PARSEOP_METHOD) 90128c506b8Sjruoho { 90228c506b8Sjruoho /* 90328c506b8Sjruoho * Get the method argument count from "Extra" and save 90428c506b8Sjruoho * it in the namespace node 90528c506b8Sjruoho */ 90628c506b8Sjruoho Node->Value = (UINT32) Op->Asl.Extra; 90728c506b8Sjruoho } 90828c506b8Sjruoho 90928c506b8Sjruoho return_ACPI_STATUS (Status); 91028c506b8Sjruoho } 91128c506b8Sjruoho 91228c506b8Sjruoho 91328c506b8Sjruoho /******************************************************************************* 91428c506b8Sjruoho * 915*7ab6b89bSchristos * FUNCTION: LdCheckSpecialNames 916*7ab6b89bSchristos * 917*7ab6b89bSchristos * PARAMETERS: Node - Node that represents the named object 918*7ab6b89bSchristos * Op - Named object declaring this named object 919*7ab6b89bSchristos * 920*7ab6b89bSchristos * RETURN: None 921*7ab6b89bSchristos * 922*7ab6b89bSchristos * DESCRIPTION: Check if certain named objects are declared in the incorrect 923*7ab6b89bSchristos * scope. Special named objects are listed in 924*7ab6b89bSchristos * AslGbl_SpecialNamedObjects and can only be declared at the root 925*7ab6b89bSchristos * scope. _UID inside of a processor declaration must not be a 926*7ab6b89bSchristos * string. 927*7ab6b89bSchristos * 928*7ab6b89bSchristos ******************************************************************************/ 929*7ab6b89bSchristos 930*7ab6b89bSchristos static void 931*7ab6b89bSchristos LdCheckSpecialNames ( 932*7ab6b89bSchristos ACPI_NAMESPACE_NODE *Node, 933*7ab6b89bSchristos ACPI_PARSE_OBJECT *Op) 934*7ab6b89bSchristos { 935*7ab6b89bSchristos UINT32 i; 936*7ab6b89bSchristos 937*7ab6b89bSchristos 938*7ab6b89bSchristos for (i = 0; i < MAX_SPECIAL_NAMES; i++) 939*7ab6b89bSchristos { 940*7ab6b89bSchristos if (ACPI_COMPARE_NAMESEG(Node->Name.Ascii, AslGbl_SpecialNamedObjects[i]) && 941*7ab6b89bSchristos Node->Parent != AcpiGbl_RootNode) 942*7ab6b89bSchristos { 943*7ab6b89bSchristos AslError (ASL_ERROR, ASL_MSG_INVALID_SPECIAL_NAME, Op, Op->Asl.ExternalName); 944*7ab6b89bSchristos return; 945*7ab6b89bSchristos } 946*7ab6b89bSchristos } 947*7ab6b89bSchristos 948*7ab6b89bSchristos if (ACPI_COMPARE_NAMESEG (Node->Name.Ascii, "_UID") && 949*7ab6b89bSchristos Node->Parent->Type == ACPI_TYPE_PROCESSOR && 950*7ab6b89bSchristos Node->Type == ACPI_TYPE_STRING) 951*7ab6b89bSchristos { 952*7ab6b89bSchristos AslError (ASL_ERROR, ASL_MSG_INVALID_PROCESSOR_UID , Op, "found a string"); 953*7ab6b89bSchristos } 954*7ab6b89bSchristos } 955*7ab6b89bSchristos 956*7ab6b89bSchristos 957*7ab6b89bSchristos /******************************************************************************* 958*7ab6b89bSchristos * 95928c506b8Sjruoho * FUNCTION: LdNamespace2Begin 96028c506b8Sjruoho * 96128c506b8Sjruoho * PARAMETERS: ASL_WALK_CALLBACK 96228c506b8Sjruoho * 96328c506b8Sjruoho * RETURN: Status 96428c506b8Sjruoho * 96528c506b8Sjruoho * DESCRIPTION: Descending callback used during the pass 2 parse tree walk. 96628c506b8Sjruoho * Second pass resolves some forward references. 96728c506b8Sjruoho * 96828c506b8Sjruoho * Notes: 96928c506b8Sjruoho * Currently only needs to handle the Alias operator. 97028c506b8Sjruoho * Could be used to allow forward references from the Scope() operator, but 97128c506b8Sjruoho * the MS interpreter does not allow this, so this compiler does not either. 97228c506b8Sjruoho * 97328c506b8Sjruoho ******************************************************************************/ 97428c506b8Sjruoho 97528c506b8Sjruoho static ACPI_STATUS 97628c506b8Sjruoho LdNamespace2Begin ( 97728c506b8Sjruoho ACPI_PARSE_OBJECT *Op, 97828c506b8Sjruoho UINT32 Level, 97928c506b8Sjruoho void *Context) 98028c506b8Sjruoho { 98128c506b8Sjruoho ACPI_WALK_STATE *WalkState = (ACPI_WALK_STATE *) Context; 98228c506b8Sjruoho ACPI_STATUS Status; 98328c506b8Sjruoho ACPI_NAMESPACE_NODE *Node; 98428c506b8Sjruoho ACPI_OBJECT_TYPE ObjectType; 98528c506b8Sjruoho BOOLEAN ForceNewScope = FALSE; 98628c506b8Sjruoho ACPI_PARSE_OBJECT *Arg; 98728c506b8Sjruoho char *Path; 98828c506b8Sjruoho ACPI_NAMESPACE_NODE *TargetNode; 98928c506b8Sjruoho 99028c506b8Sjruoho 99128c506b8Sjruoho ACPI_FUNCTION_NAME (LdNamespace2Begin); 99228c506b8Sjruoho ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Op %p [%s]\n", 99328c506b8Sjruoho Op, Op->Asl.ParseOpName)); 99428c506b8Sjruoho 99528c506b8Sjruoho 99628c506b8Sjruoho /* Ignore Ops with no namespace node */ 99728c506b8Sjruoho 99828c506b8Sjruoho Node = Op->Asl.Node; 99928c506b8Sjruoho if (!Node) 100028c506b8Sjruoho { 100128c506b8Sjruoho return (AE_OK); 100228c506b8Sjruoho } 100328c506b8Sjruoho 100428c506b8Sjruoho /* Get the type to determine if we should push the scope */ 100528c506b8Sjruoho 100628c506b8Sjruoho if ((Op->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG) && 1007ae01dbf5Schristos (Op->Asl.CompileFlags == OP_IS_RESOURCE_DESC)) 100828c506b8Sjruoho { 100928c506b8Sjruoho ObjectType = ACPI_TYPE_LOCAL_RESOURCE; 101028c506b8Sjruoho } 101128c506b8Sjruoho else 101228c506b8Sjruoho { 101328c506b8Sjruoho ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode); 101428c506b8Sjruoho } 101528c506b8Sjruoho 101628c506b8Sjruoho /* Push scope for Resource Templates */ 101728c506b8Sjruoho 101828c506b8Sjruoho if (Op->Asl.ParseOpcode == PARSEOP_NAME) 101928c506b8Sjruoho { 1020ae01dbf5Schristos if (Op->Asl.CompileFlags & OP_IS_RESOURCE_DESC) 102128c506b8Sjruoho { 102228c506b8Sjruoho ForceNewScope = TRUE; 102328c506b8Sjruoho } 102428c506b8Sjruoho } 102528c506b8Sjruoho 102628c506b8Sjruoho /* Push the scope stack */ 102728c506b8Sjruoho 102828c506b8Sjruoho if (ForceNewScope || AcpiNsOpensScope (ObjectType)) 102928c506b8Sjruoho { 103028c506b8Sjruoho Status = AcpiDsScopeStackPush (Node, ObjectType, WalkState); 103128c506b8Sjruoho if (ACPI_FAILURE (Status)) 103228c506b8Sjruoho { 103328c506b8Sjruoho return_ACPI_STATUS (Status); 103428c506b8Sjruoho } 103528c506b8Sjruoho } 103628c506b8Sjruoho 103728c506b8Sjruoho if (Op->Asl.ParseOpcode == PARSEOP_ALIAS) 103828c506b8Sjruoho { 10397efa3256Schristos /* 10407efa3256Schristos * Complete the alias node by getting and saving the target node. 10417efa3256Schristos * First child is the alias target 10427efa3256Schristos */ 104328c506b8Sjruoho Arg = Op->Asl.Child; 104428c506b8Sjruoho 104528c506b8Sjruoho /* Get the target pathname */ 104628c506b8Sjruoho 104728c506b8Sjruoho Path = Arg->Asl.Namepath; 104828c506b8Sjruoho if (!Path) 104928c506b8Sjruoho { 105028c506b8Sjruoho Status = UtInternalizeName (Arg->Asl.ExternalName, &Path); 105128c506b8Sjruoho if (ACPI_FAILURE (Status)) 105228c506b8Sjruoho { 105328c506b8Sjruoho return (Status); 105428c506b8Sjruoho } 105528c506b8Sjruoho } 105628c506b8Sjruoho 105728c506b8Sjruoho /* Get the NS node associated with the target. It must exist. */ 105828c506b8Sjruoho 105928c506b8Sjruoho Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ACPI_TYPE_ANY, 106028c506b8Sjruoho ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE, 106128c506b8Sjruoho WalkState, &TargetNode); 106228c506b8Sjruoho if (ACPI_FAILURE (Status)) 106328c506b8Sjruoho { 106428c506b8Sjruoho if (Status == AE_NOT_FOUND) 106528c506b8Sjruoho { 10667efa3256Schristos /* Standalone NameSeg vs. NamePath */ 106728c506b8Sjruoho 10685b948c02Schristos if (strlen (Arg->Asl.ExternalName) == ACPI_NAMESEG_SIZE) 10697efa3256Schristos { 10707efa3256Schristos AslError (ASL_ERROR, ASL_MSG_NOT_FOUND, Op, 10717efa3256Schristos Arg->Asl.ExternalName); 10727efa3256Schristos } 10737efa3256Schristos else 10747efa3256Schristos { 10757efa3256Schristos AslError (ASL_ERROR, ASL_MSG_NAMEPATH_NOT_EXIST, Op, 10767efa3256Schristos Arg->Asl.ExternalName); 10777efa3256Schristos } 10787efa3256Schristos 10797efa3256Schristos #if 0 10807efa3256Schristos /* 10817efa3256Schristos * NOTE: Removed 10/2018 to enhance compiler error reporting. No 10827efa3256Schristos * regressions seen. 10837efa3256Schristos */ 108428c506b8Sjruoho /* 108528c506b8Sjruoho * The name was not found, go ahead and create it. 108628c506b8Sjruoho * This prevents more errors later. 108728c506b8Sjruoho */ 108828c506b8Sjruoho Status = AcpiNsLookup (WalkState->ScopeInfo, Path, 10897efa3256Schristos ACPI_TYPE_ANY, ACPI_IMODE_LOAD_PASS1, 10907efa3256Schristos ACPI_NS_NO_UPSEARCH, WalkState, &Node); 10917efa3256Schristos #endif 10927efa3256Schristos return (Status); 10937efa3256Schristos /* Removed: return (AE_OK)*/ 109428c506b8Sjruoho } 109528c506b8Sjruoho 109628c506b8Sjruoho AslCoreSubsystemError (Op, Status, 109728c506b8Sjruoho "Failure from namespace lookup", FALSE); 109828c506b8Sjruoho return (AE_OK); 109928c506b8Sjruoho } 110028c506b8Sjruoho 110128c506b8Sjruoho /* Save the target node within the alias node */ 110228c506b8Sjruoho 110328c506b8Sjruoho Node->Object = ACPI_CAST_PTR (ACPI_OPERAND_OBJECT, TargetNode); 110428c506b8Sjruoho } 110528c506b8Sjruoho 110628c506b8Sjruoho return (AE_OK); 110728c506b8Sjruoho } 110828c506b8Sjruoho 110928c506b8Sjruoho 111028c506b8Sjruoho /******************************************************************************* 111128c506b8Sjruoho * 111228c506b8Sjruoho * FUNCTION: LdCommonNamespaceEnd 111328c506b8Sjruoho * 111428c506b8Sjruoho * PARAMETERS: ASL_WALK_CALLBACK 111528c506b8Sjruoho * 111628c506b8Sjruoho * RETURN: Status 111728c506b8Sjruoho * 111828c506b8Sjruoho * DESCRIPTION: Ascending callback used during the loading of the namespace, 111928c506b8Sjruoho * We only need to worry about managing the scope stack here. 112028c506b8Sjruoho * 112128c506b8Sjruoho ******************************************************************************/ 112228c506b8Sjruoho 112328c506b8Sjruoho static ACPI_STATUS 112428c506b8Sjruoho LdCommonNamespaceEnd ( 112528c506b8Sjruoho ACPI_PARSE_OBJECT *Op, 112628c506b8Sjruoho UINT32 Level, 112728c506b8Sjruoho void *Context) 112828c506b8Sjruoho { 112928c506b8Sjruoho ACPI_WALK_STATE *WalkState = (ACPI_WALK_STATE *) Context; 113028c506b8Sjruoho ACPI_OBJECT_TYPE ObjectType; 113128c506b8Sjruoho BOOLEAN ForceNewScope = FALSE; 113228c506b8Sjruoho 113328c506b8Sjruoho 113428c506b8Sjruoho ACPI_FUNCTION_NAME (LdCommonNamespaceEnd); 113528c506b8Sjruoho 113628c506b8Sjruoho 113728c506b8Sjruoho /* We are only interested in opcodes that have an associated name */ 113828c506b8Sjruoho 113928c506b8Sjruoho if (!Op->Asl.Namepath) 114028c506b8Sjruoho { 114128c506b8Sjruoho return (AE_OK); 114228c506b8Sjruoho } 114328c506b8Sjruoho 114428c506b8Sjruoho /* Get the type to determine if we should pop the scope */ 114528c506b8Sjruoho 114628c506b8Sjruoho if ((Op->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG) && 1147ae01dbf5Schristos (Op->Asl.CompileFlags == OP_IS_RESOURCE_DESC)) 114828c506b8Sjruoho { 114928c506b8Sjruoho /* TBD: Merge into AcpiDsMapNamedOpcodeToDataType */ 115028c506b8Sjruoho 115128c506b8Sjruoho ObjectType = ACPI_TYPE_LOCAL_RESOURCE; 115228c506b8Sjruoho } 115328c506b8Sjruoho else 115428c506b8Sjruoho { 115528c506b8Sjruoho ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode); 115628c506b8Sjruoho } 115728c506b8Sjruoho 115828c506b8Sjruoho /* Pop scope that was pushed for Resource Templates */ 115928c506b8Sjruoho 116028c506b8Sjruoho if (Op->Asl.ParseOpcode == PARSEOP_NAME) 116128c506b8Sjruoho { 1162ae01dbf5Schristos if (Op->Asl.CompileFlags & OP_IS_RESOURCE_DESC) 116328c506b8Sjruoho { 116428c506b8Sjruoho ForceNewScope = TRUE; 116528c506b8Sjruoho } 116628c506b8Sjruoho } 116728c506b8Sjruoho 116828c506b8Sjruoho /* Pop the scope stack */ 116928c506b8Sjruoho 117028c506b8Sjruoho if (ForceNewScope || AcpiNsOpensScope (ObjectType)) 117128c506b8Sjruoho { 117228c506b8Sjruoho ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, 117328c506b8Sjruoho "(%s): Popping scope for Op [%s] %p\n", 117428c506b8Sjruoho AcpiUtGetTypeName (ObjectType), Op->Asl.ParseOpName, Op)); 117528c506b8Sjruoho 117628c506b8Sjruoho (void) AcpiDsScopeStackPop (WalkState); 117728c506b8Sjruoho } 117828c506b8Sjruoho 117928c506b8Sjruoho return (AE_OK); 118028c506b8Sjruoho } 1181