Path: blob/main/sys/contrib/dev/acpica/compiler/aslload.c
48371 views
/******************************************************************************1*2* Module Name: aslload - compiler namespace load callbacks3*4*****************************************************************************/56/******************************************************************************7*8* 1. Copyright Notice9*10* Some or all of this work - Copyright (c) 1999 - 2025, Intel Corp.11* All rights reserved.12*13* 2. License14*15* 2.1. This is your license from Intel Corp. under its intellectual property16* rights. You may have additional license terms from the party that provided17* you this software, covering your right to use that party's intellectual18* property rights.19*20* 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a21* copy of the source code appearing in this file ("Covered Code") an22* irrevocable, perpetual, worldwide license under Intel's copyrights in the23* base code distributed originally by Intel ("Original Intel Code") to copy,24* make derivatives, distribute, use and display any portion of the Covered25* Code in any form, with the right to sublicense such rights; and26*27* 2.3. Intel grants Licensee a non-exclusive and non-transferable patent28* license (with the right to sublicense), under only those claims of Intel29* patents that are infringed by the Original Intel Code, to make, use, sell,30* offer to sell, and import the Covered Code and derivative works thereof31* solely to the minimum extent necessary to exercise the above copyright32* license, and in no event shall the patent license extend to any additions33* to or modifications of the Original Intel Code. No other license or right34* is granted directly or by implication, estoppel or otherwise;35*36* The above copyright and patent license is granted only if the following37* conditions are met:38*39* 3. Conditions40*41* 3.1. Redistribution of Source with Rights to Further Distribute Source.42* Redistribution of source code of any substantial portion of the Covered43* Code or modification with rights to further distribute source must include44* the above Copyright Notice, the above License, this list of Conditions,45* and the following Disclaimer and Export Compliance provision. In addition,46* Licensee must cause all Covered Code to which Licensee contributes to47* contain a file documenting the changes Licensee made to create that Covered48* Code and the date of any change. Licensee must include in that file the49* documentation of any changes made by any predecessor Licensee. Licensee50* must include a prominent statement that the modification is derived,51* directly or indirectly, from Original Intel Code.52*53* 3.2. Redistribution of Source with no Rights to Further Distribute Source.54* Redistribution of source code of any substantial portion of the Covered55* Code or modification without rights to further distribute source must56* include the following Disclaimer and Export Compliance provision in the57* documentation and/or other materials provided with distribution. In58* addition, Licensee may not authorize further sublicense of source of any59* portion of the Covered Code, and must include terms to the effect that the60* license from Licensee to its licensee is limited to the intellectual61* property embodied in the software Licensee provides to its licensee, and62* not to intellectual property embodied in modifications its licensee may63* make.64*65* 3.3. Redistribution of Executable. Redistribution in executable form of any66* substantial portion of the Covered Code or modification must reproduce the67* above Copyright Notice, and the following Disclaimer and Export Compliance68* provision in the documentation and/or other materials provided with the69* distribution.70*71* 3.4. Intel retains all right, title, and interest in and to the Original72* Intel Code.73*74* 3.5. Neither the name Intel nor any other trademark owned or controlled by75* Intel shall be used in advertising or otherwise to promote the sale, use or76* other dealings in products derived from or relating to the Covered Code77* without prior written authorization from Intel.78*79* 4. Disclaimer and Export Compliance80*81* 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED82* HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE83* IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,84* INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY85* UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY86* IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A87* PARTICULAR PURPOSE.88*89* 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES90* OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR91* COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,92* SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY93* CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL94* HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS95* SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY96* LIMITED REMEDY.97*98* 4.3. Licensee shall not export, either directly or indirectly, any of this99* software or system incorporating such software without first obtaining any100* required license or other approval from the U. S. Department of Commerce or101* any other agency or department of the United States Government. In the102* event Licensee exports any such software from the United States or103* re-exports any such software from a foreign destination, Licensee shall104* ensure that the distribution and export/re-export of the software is in105* compliance with all laws, regulations, orders, or other restrictions of the106* U.S. Export Administration Regulations. Licensee agrees that neither it nor107* any of its subsidiaries will export/re-export any technical data, process,108* software, or service, directly or indirectly, to any country for which the109* United States government or any agency thereof requires an export license,110* other governmental approval, or letter of assurance, without first obtaining111* such license, approval or letter.112*113*****************************************************************************114*115* Alternatively, you may choose to be licensed under the terms of the116* following license:117*118* Redistribution and use in source and binary forms, with or without119* modification, are permitted provided that the following conditions120* are met:121* 1. Redistributions of source code must retain the above copyright122* notice, this list of conditions, and the following disclaimer,123* without modification.124* 2. Redistributions in binary form must reproduce at minimum a disclaimer125* substantially similar to the "NO WARRANTY" disclaimer below126* ("Disclaimer") and any redistribution must be conditioned upon127* including a substantially similar Disclaimer requirement for further128* binary redistribution.129* 3. Neither the names of the above-listed copyright holders nor the names130* of any contributors may be used to endorse or promote products derived131* from this software without specific prior written permission.132*133* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS134* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT135* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR136* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT137* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,138* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT139* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,140* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY141* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT142* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE143* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.144*145* Alternatively, you may choose to be licensed under the terms of the146* GNU General Public License ("GPL") version 2 as published by the Free147* Software Foundation.148*149*****************************************************************************/150151#include <contrib/dev/acpica/compiler/aslcompiler.h>152#include <contrib/dev/acpica/include/amlcode.h>153#include <contrib/dev/acpica/include/acdispat.h>154#include <contrib/dev/acpica/include/acnamesp.h>155#include <contrib/dev/acpica/include/acparser.h>156#include "aslcompiler.y.h"157158159#define _COMPONENT ACPI_COMPILER160ACPI_MODULE_NAME ("aslload")161162/* Local prototypes */163164static ACPI_STATUS165LdLoadFieldElements (166UINT32 AmlType,167ACPI_PARSE_OBJECT *Op,168ACPI_WALK_STATE *WalkState);169170static ACPI_STATUS171LdLoadResourceElements (172ACPI_PARSE_OBJECT *Op,173ACPI_WALK_STATE *WalkState);174175static ACPI_STATUS176LdNamespace1Begin (177ACPI_PARSE_OBJECT *Op,178UINT32 Level,179void *Context);180181static ACPI_STATUS182LdNamespace2Begin (183ACPI_PARSE_OBJECT *Op,184UINT32 Level,185void *Context);186187static ACPI_STATUS188LdCommonNamespaceEnd (189ACPI_PARSE_OBJECT *Op,190UINT32 Level,191void *Context);192193static void194LdCheckSpecialNames (195ACPI_NAMESPACE_NODE *Node,196ACPI_PARSE_OBJECT *Op);197198static ACPI_STATUS199LdAnalyzeExternals (200ACPI_NAMESPACE_NODE *Node,201ACPI_PARSE_OBJECT *Op,202ACPI_OBJECT_TYPE ExternalOpType,203ACPI_WALK_STATE *WalkState);204205206/*******************************************************************************207*208* FUNCTION: LdLoadNamespace209*210* PARAMETERS: RootOp - Root of the parse tree211*212* RETURN: Status213*214* DESCRIPTION: Perform a walk of the parse tree that in turn loads all of the215* named ASL/AML objects into the namespace. The namespace is216* constructed in order to resolve named references and references217* to named fields within resource templates/descriptors.218*219******************************************************************************/220221ACPI_STATUS222LdLoadNamespace (223ACPI_PARSE_OBJECT *RootOp)224{225ACPI_WALK_STATE *WalkState;226227228/* Create a new walk state */229230WalkState = AcpiDsCreateWalkState (0, NULL, NULL, NULL);231if (!WalkState)232{233return (AE_NO_MEMORY);234}235236/* Walk the entire parse tree, first pass */237238TrWalkParseTree (RootOp, ASL_WALK_VISIT_TWICE, LdNamespace1Begin,239LdCommonNamespaceEnd, WalkState);240241/* Second pass to handle forward references */242243TrWalkParseTree (RootOp, ASL_WALK_VISIT_TWICE, LdNamespace2Begin,244LdCommonNamespaceEnd, WalkState);245246/* Dump the namespace if debug is enabled */247248if (AcpiDbgLevel & ACPI_LV_TABLES)249{250AcpiNsDumpTables (ACPI_NS_ALL, ACPI_UINT32_MAX);251}252253ACPI_FREE (WalkState);254return (AE_OK);255}256257258/*******************************************************************************259*260* FUNCTION: LdLoadFieldElements261*262* PARAMETERS: AmlType - Type to search263* Op - Parent node (Field)264* WalkState - Current walk state265*266* RETURN: Status267*268* DESCRIPTION: Enter the named elements of the field (children of the parent)269* into the namespace.270*271******************************************************************************/272273static ACPI_STATUS274LdLoadFieldElements (275UINT32 AmlType,276ACPI_PARSE_OBJECT *Op,277ACPI_WALK_STATE *WalkState)278{279ACPI_PARSE_OBJECT *Child = NULL;280ACPI_PARSE_OBJECT *SourceRegion;281ACPI_NAMESPACE_NODE *Node;282ACPI_STATUS Status;283char *ExternalPath;284285286SourceRegion = UtGetArg (Op, 0);287if (SourceRegion)288{289Status = AcpiNsLookup (WalkState->ScopeInfo,290SourceRegion->Asl.Value.String, AmlType, ACPI_IMODE_EXECUTE,291ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE, NULL, &Node);292if (Status == AE_NOT_FOUND)293{294/*295* If the named object is not found, it means that it is either a296* forward reference or the named object does not exist.297*/298SourceRegion->Asl.CompileFlags |= OP_NOT_FOUND_DURING_LOAD;299}300}301302/* Get the first named field element */303304switch (Op->Asl.AmlOpcode)305{306case AML_BANK_FIELD_OP:307308Child = UtGetArg (Op, 6);309break;310311case AML_INDEX_FIELD_OP:312313Child = UtGetArg (Op, 5);314break;315316case AML_FIELD_OP:317318Child = UtGetArg (Op, 4);319break;320321default:322323/* No other opcodes should arrive here */324325return (AE_BAD_PARAMETER);326}327328/* Enter all elements into the namespace */329330while (Child)331{332switch (Child->Asl.AmlOpcode)333{334case AML_INT_RESERVEDFIELD_OP:335case AML_INT_ACCESSFIELD_OP:336case AML_INT_CONNECTION_OP:337break;338339default:340341Status = AcpiNsLookup (WalkState->ScopeInfo,342Child->Asl.Value.String,343ACPI_TYPE_LOCAL_REGION_FIELD,344ACPI_IMODE_LOAD_PASS1,345ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE |346ACPI_NS_ERROR_IF_FOUND, NULL, &Node);347if (ACPI_FAILURE (Status))348{349if (Status != AE_ALREADY_EXISTS)350{351AslError (ASL_ERROR, ASL_MSG_CORE_EXCEPTION, Child,352Child->Asl.Value.String);353return (Status);354}355else if (Status == AE_ALREADY_EXISTS &&356(Node->Flags & ANOBJ_IS_EXTERNAL))357{358Node->Type = (UINT8) ACPI_TYPE_LOCAL_REGION_FIELD;359Node->Flags &= ~ANOBJ_IS_EXTERNAL;360}361else362{363/*364* The name already exists in this scope365* But continue processing the elements366*/367ExternalPath = AcpiNsGetNormalizedPathname (Node, TRUE);368369AslDualParseOpError (ASL_ERROR, ASL_MSG_NAME_EXISTS, Child,370ExternalPath, ASL_MSG_FOUND_HERE, Node->Op,371ExternalPath);372373if (ExternalPath)374{375ACPI_FREE (ExternalPath);376}377}378}379else380{381Child->Asl.Node = Node;382Node->Op = Child;383}384break;385}386387Child = Child->Asl.Next;388}389390return (AE_OK);391}392393394/*******************************************************************************395*396* FUNCTION: LdLoadResourceElements397*398* PARAMETERS: Op - Parent node (Resource Descriptor)399* WalkState - Current walk state400*401* RETURN: Status402*403* DESCRIPTION: Enter the named elements of the resource descriptor (children404* of the parent) into the namespace.405*406* NOTE: In the real AML namespace, these named elements never exist. But407* we simply use the namespace here as a symbol table so we can look408* them up as they are referenced.409*410******************************************************************************/411412static ACPI_STATUS413LdLoadResourceElements (414ACPI_PARSE_OBJECT *Op,415ACPI_WALK_STATE *WalkState)416{417ACPI_PARSE_OBJECT *InitializerOp = NULL;418ACPI_NAMESPACE_NODE *Node;419ACPI_STATUS Status;420char *ExternalPath;421422423/*424* Enter the resource name into the namespace. Name must not already exist.425* This opens a scope, so later field names are guaranteed to be new/unique.426*/427Status = AcpiNsLookup (WalkState->ScopeInfo, Op->Asl.Namepath,428ACPI_TYPE_LOCAL_RESOURCE, ACPI_IMODE_LOAD_PASS1,429ACPI_NS_NO_UPSEARCH | ACPI_NS_ERROR_IF_FOUND,430WalkState, &Node);431if (ACPI_FAILURE (Status))432{433if (Status == AE_ALREADY_EXISTS)434{435/* Actual node causing the error was saved in ParentMethod */436437ExternalPath = AcpiNsGetNormalizedPathname (Node, TRUE);438439AslDualParseOpError (ASL_ERROR, ASL_MSG_NAME_EXISTS,440(ACPI_PARSE_OBJECT *) Op->Asl.ParentMethod,441ExternalPath, ASL_MSG_FOUND_HERE, Node->Op,442ExternalPath);443444if (ExternalPath)445{446ACPI_FREE (ExternalPath);447}448return (AE_OK);449}450return (Status);451}452453Node->Value = (UINT32) Op->Asl.Value.Integer;454Node->Op = Op;455Op->Asl.Node = Node;456457/*458* Now enter the predefined fields, for easy lookup when referenced459* by the source ASL460*/461InitializerOp = ASL_GET_CHILD_NODE (Op);462while (InitializerOp)463{464if (InitializerOp->Asl.ExternalName)465{466Status = AcpiNsLookup (WalkState->ScopeInfo,467InitializerOp->Asl.ExternalName,468ACPI_TYPE_LOCAL_RESOURCE_FIELD, ACPI_IMODE_LOAD_PASS1,469ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE, NULL, &Node);470if (ACPI_FAILURE (Status))471{472return (Status);473}474475/*476* Store the field offset and length in the namespace node477* so it can be used when the field is referenced478*/479Node->Value = InitializerOp->Asl.Value.Tag.BitOffset;480Node->Length = InitializerOp->Asl.Value.Tag.BitLength;481InitializerOp->Asl.Node = Node;482Node->Op = InitializerOp;483}484485InitializerOp = ASL_GET_PEER_NODE (InitializerOp);486}487488return (AE_OK);489}490491492/*******************************************************************************493*494* FUNCTION: LdNamespace1Begin495*496* PARAMETERS: ASL_WALK_CALLBACK497*498* RETURN: Status499*500* DESCRIPTION: Descending callback used during the parse tree walk. If this501* is a named AML opcode, enter into the namespace502*503******************************************************************************/504505static ACPI_STATUS506LdNamespace1Begin (507ACPI_PARSE_OBJECT *Op,508UINT32 Level,509void *Context)510{511ACPI_WALK_STATE *WalkState = (ACPI_WALK_STATE *) Context;512ACPI_NAMESPACE_NODE *Node;513ACPI_PARSE_OBJECT *MethodOp;514ACPI_STATUS Status;515ACPI_OBJECT_TYPE ObjectType;516char *Path;517UINT32 Flags = ACPI_NS_NO_UPSEARCH;518ACPI_PARSE_OBJECT *Arg;519UINT32 i;520BOOLEAN ForceNewScope = FALSE;521const ACPI_OPCODE_INFO *OpInfo;522ACPI_PARSE_OBJECT *ParentOp;523char *ExternalPath;524525526ACPI_FUNCTION_NAME (LdNamespace1Begin);527528529ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Op %p [%s]\n",530Op, Op->Asl.ParseOpName));531532/*533* We are only interested in opcodes that have an associated name534* (or multiple names)535*/536switch (Op->Asl.AmlOpcode)537{538case AML_INDEX_FIELD_OP:539540Status = LdLoadFieldElements (ACPI_TYPE_LOCAL_REGION_FIELD, Op, WalkState);541return (Status);542543case AML_BANK_FIELD_OP:544case AML_FIELD_OP:545546Status = LdLoadFieldElements (ACPI_TYPE_REGION, Op, WalkState);547return (Status);548549case AML_INT_CONNECTION_OP:550551if (Op->Asl.Child->Asl.AmlOpcode != AML_INT_NAMEPATH_OP)552{553break;554}555556Arg = Op->Asl.Child;557Status = AcpiNsLookup (WalkState->ScopeInfo, Arg->Asl.ExternalName,558ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT,559WalkState, &Node);560if (ACPI_FAILURE (Status))561{562break;563}564565break;566567default:568569/* All other opcodes go below */570571break;572}573574/* Check if this object has already been installed in the namespace */575576if (Op->Asl.Node)577{578return (AE_OK);579}580581/* Check for a possible illegal forward reference */582583if ((Op->Asl.ParseOpcode == PARSEOP_NAMESEG) ||584(Op->Asl.ParseOpcode == PARSEOP_NAMESTRING) ||585(Op->Asl.ParseOpcode == PARSEOP_METHODCALL))586{587/*588* Op->Asl.Namepath will be NULL for these opcodes.589* These opcodes are guaranteed to have a parent.590* Examine the parent opcode.591*/592ParentOp = Op->Asl.Parent;593OpInfo = AcpiPsGetOpcodeInfo (ParentOp->Asl.AmlOpcode);594595/*596* Exclude all operators that actually declare a new name:597* Name (ABCD, 1) -> Ignore (AML_CLASS_NAMED_OBJECT)598* We only want references to named objects:599* Store (2, WXYZ) -> Attempt to resolve the name600*/601if ((Op->Asl.ParseOpcode != PARSEOP_METHODCALL) &&602(OpInfo->Class == AML_CLASS_NAMED_OBJECT))603{604return (AE_OK);605}606607/*608* Check if the referenced object exists at this point during609* the load:610* 1) If it exists, then this cannot be a forward reference.611* 2) If it does not exist, it could be a forward reference or612* it truly does not exist (and no external declaration).613*/614Status = AcpiNsLookup (WalkState->ScopeInfo,615Op->Asl.Value.Name, ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,616ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE,617WalkState, &Node);618if (Status == AE_NOT_FOUND)619{620/*621* This is either a forward reference or the object truly622* does not exist. The two cases can only be differentiated623* during the cross-reference stage later. Mark the Op/Name624* as not-found for now to indicate the need for further625* processing.626*627* Special case: Allow forward references from elements of628* Package objects. This provides compatibility with other629* ACPI implementations. To correctly implement this, the630* ACPICA table load defers package resolution until the entire631* namespace has been loaded.632*/633if ((ParentOp->Asl.ParseOpcode != PARSEOP_PACKAGE) &&634(ParentOp->Asl.ParseOpcode != PARSEOP_VAR_PACKAGE))635{636Op->Asl.CompileFlags |= OP_NOT_FOUND_DURING_LOAD;637}638639return (AE_OK);640}641642return (Status);643}644645Path = Op->Asl.Namepath;646if (!Path)647{648return (AE_OK);649}650651/* Map the raw opcode into an internal object type */652653switch (Op->Asl.ParseOpcode)654{655case PARSEOP_NAME:656657Arg = Op->Asl.Child; /* Get the NameSeg/NameString node */658Arg = Arg->Asl.Next; /* First peer is the object to be associated with the name */659660/*661* If this name refers to a ResourceTemplate, we will need to open662* a new scope so that the resource subfield names can be entered into663* the namespace underneath this name664*/665if (Op->Asl.CompileFlags & OP_IS_RESOURCE_DESC)666{667ForceNewScope = TRUE;668}669670/* Get the data type associated with the named object, not the name itself */671672/* Log2 loop to convert from Btype (binary) to Etype (encoded) */673674ObjectType = 1;675for (i = 1; i < Arg->Asl.AcpiBtype; i *= 2)676{677ObjectType++;678}679break;680681case PARSEOP_EXTERNAL:682/*683* "External" simply enters a name and type into the namespace.684* We must be careful to not open a new scope, however, no matter685* what type the external name refers to (e.g., a method)686*687* first child is name, next child is ObjectType688*/689ObjectType = (UINT8) Op->Asl.Child->Asl.Next->Asl.Value.Integer;690691/*692* We will mark every new node along the path as "External". This693* allows some or all of the nodes to be created later in the ASL694* code. Handles cases like this:695*696* External (\_SB_.PCI0.ABCD, IntObj)697* Scope (_SB_)698* {699* Device (PCI0)700* {701* }702* }703* Method (X)704* {705* Store (\_SB_.PCI0.ABCD, Local0)706* }707*/708Flags |= ACPI_NS_EXTERNAL | ACPI_NS_DONT_OPEN_SCOPE;709break;710711case PARSEOP_DEFAULT_ARG:712713if (Op->Asl.CompileFlags == OP_IS_RESOURCE_DESC)714{715Status = LdLoadResourceElements (Op, WalkState);716return_ACPI_STATUS (Status);717}718719ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode);720break;721722case PARSEOP_SCOPE:723/*724* The name referenced by Scope(Name) must already exist at this point.725* In other words, forward references for Scope() are not supported.726* The only real reason for this is that the MS interpreter cannot727* handle this case. Perhaps someday this case can go away.728*/729Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ACPI_TYPE_ANY,730ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT, WalkState, &Node);731if (ACPI_FAILURE (Status))732{733if (Status == AE_NOT_FOUND)734{735/* The name was not found, go ahead and create it */736737Status = AcpiNsLookup (WalkState->ScopeInfo, Path,738ACPI_TYPE_LOCAL_SCOPE, ACPI_IMODE_LOAD_PASS1,739Flags, WalkState, &Node);740if (ACPI_FAILURE (Status))741{742return_ACPI_STATUS (Status);743}744745/* However, this is an error -- operand to Scope must exist */746747if (strlen (Op->Asl.ExternalName) == ACPI_NAMESEG_SIZE)748{749AslError (ASL_ERROR, ASL_MSG_NOT_FOUND, Op,750Op->Asl.ExternalName);751}752else753{754AslError (ASL_ERROR, ASL_MSG_NAMEPATH_NOT_EXIST, Op,755Op->Asl.ExternalName);756}757758goto FinishNode;759}760761AslCoreSubsystemError (Op, Status,762"Failure from namespace lookup", FALSE);763764return_ACPI_STATUS (Status);765}766else /* Status AE_OK */767{768/*769* Do not allow references to external scopes from the DSDT.770* This is because the DSDT is always loaded first, and the771* external reference cannot be resolved -- causing a runtime772* error because Scope() must be resolved immediately.773* 10/2015.774*/775if ((Node->Flags & ANOBJ_IS_EXTERNAL) &&776(ACPI_COMPARE_NAMESEG (AslGbl_TableSignature, "DSDT")))777{778/* However, allowed if the reference is within a method */779780MethodOp = Op->Asl.Parent;781while (MethodOp &&782(MethodOp->Asl.ParseOpcode != PARSEOP_METHOD))783{784MethodOp = MethodOp->Asl.Parent;785}786787if (!MethodOp)788{789/* Not in a control method, error */790791AslError (ASL_ERROR, ASL_MSG_CROSS_TABLE_SCOPE, Op, NULL);792}793}794}795796/* We found a node with this name, now check the type */797798switch (Node->Type)799{800case ACPI_TYPE_LOCAL_SCOPE:801case ACPI_TYPE_DEVICE:802case ACPI_TYPE_POWER:803case ACPI_TYPE_PROCESSOR:804case ACPI_TYPE_THERMAL:805806/* These are acceptable types - they all open a new scope */807break;808809case ACPI_TYPE_INTEGER:810case ACPI_TYPE_STRING:811case ACPI_TYPE_BUFFER:812/*813* These types we will allow, but we will change the type.814* This enables some existing code of the form:815*816* Name (DEB, 0)817* Scope (DEB) { ... }818*819* Which is used to workaround the fact that the MS interpreter820* does not allow Scope() forward references.821*/822sprintf (AslGbl_MsgBuffer, "%s [%s], changing type to [Scope]",823Op->Asl.ExternalName, AcpiUtGetTypeName (Node->Type));824AslError (ASL_REMARK, ASL_MSG_SCOPE_TYPE, Op, AslGbl_MsgBuffer);825826/* Switch the type to scope, open the new scope */827828Node->Type = ACPI_TYPE_LOCAL_SCOPE;829Status = AcpiDsScopeStackPush (Node, ACPI_TYPE_LOCAL_SCOPE,830WalkState);831if (ACPI_FAILURE (Status))832{833return_ACPI_STATUS (Status);834}835break;836837default:838839/* All other types are an error */840841sprintf (AslGbl_MsgBuffer, "%s [%s]", Op->Asl.ExternalName,842AcpiUtGetTypeName (Node->Type));843AslError (ASL_ERROR, ASL_MSG_SCOPE_TYPE, Op, AslGbl_MsgBuffer);844845/*846* However, switch the type to be an actual scope so847* that compilation can continue without generating a whole848* cascade of additional errors. Open the new scope.849*/850Node->Type = ACPI_TYPE_LOCAL_SCOPE;851Status = AcpiDsScopeStackPush (Node, ACPI_TYPE_LOCAL_SCOPE,852WalkState);853if (ACPI_FAILURE (Status))854{855return_ACPI_STATUS (Status);856}857break;858}859860Status = AE_OK;861goto FinishNode;862863default:864865ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode);866break;867}868869ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Loading name: %s, (%s)\n",870Op->Asl.ExternalName, AcpiUtGetTypeName (ObjectType)));871872/* The name must not already exist */873874Flags |= ACPI_NS_ERROR_IF_FOUND;875876/*877* For opcodes that enter new names into the namespace,878* all prefix NameSegs must exist.879*/880WalkState->OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode);881if (((WalkState->OpInfo->Flags & AML_NAMED) ||882(WalkState->OpInfo->Flags & AML_CREATE)) &&883(Op->Asl.AmlOpcode != AML_EXTERNAL_OP))884{885Flags |= ACPI_NS_PREFIX_MUST_EXIST;886}887888/*889* Enter the named type into the internal namespace. We enter the name890* as we go downward in the parse tree. Any necessary subobjects that891* involve arguments to the opcode must be created as we go back up the892* parse tree later.893*/894Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ObjectType,895ACPI_IMODE_LOAD_PASS1, Flags, WalkState, &Node);896if (ACPI_FAILURE (Status))897{898if (Status == AE_ALREADY_EXISTS)899{900/* The name already exists in this scope */901902if (Node->Type == ACPI_TYPE_LOCAL_SCOPE)903{904/* Allow multiple references to the same scope */905906Node->Type = (UINT8) ObjectType;907Status = AE_OK;908}909else if ((Node->Flags & ANOBJ_IS_EXTERNAL) ||910(Op->Asl.ParseOpcode == PARSEOP_EXTERNAL))911{912Status = LdAnalyzeExternals (Node, Op, ObjectType, WalkState);913if (ACPI_FAILURE (Status))914{915if (Status == AE_ERROR)916{917/*918* The use of AE_ERROR here indicates that there was a919* compiler error emitted in LdAnalyzeExternals which920* means that the caller should proceed to the next Op921* for analysis of subsequent parse objects.922*/923Status = AE_OK;924}925return_ACPI_STATUS (Status);926}927928if (!(Node->Flags & ANOBJ_IS_EXTERNAL) &&929(Op->Asl.ParseOpcode == PARSEOP_EXTERNAL))930{931/*932* If we get to here, it means that an actual definition of933* the object declared external exists. Meaning that Op934* loading this this Op should have no change to the ACPI935* namespace. By going to FinishNode, we skip the936* assignment of Node->Op = Op.937*/938goto FinishNode;939}940}941else942{943/* Valid error, object already exists */944945ExternalPath = AcpiNsGetNormalizedPathname (Node, TRUE);946947AslDualParseOpError (ASL_ERROR, ASL_MSG_NAME_EXISTS, Op,948ExternalPath, ASL_MSG_FOUND_HERE, Node->Op,949ExternalPath);950951if (ExternalPath)952{953ACPI_FREE (ExternalPath);954}955return_ACPI_STATUS (AE_OK);956}957}958else if (AE_NOT_FOUND)959{960/*961* One or more prefix NameSegs of the NamePath do not exist962* (all of them must exist). Attempt to continue compilation963* by setting the current scope to the root.964*/965Node = AcpiGbl_RootNode;966Status = AE_OK;967}968else969{970/* Flag all other errors as coming from the ACPICA core */971972AslCoreSubsystemError (Op, Status,973"Failure from namespace lookup", FALSE);974return_ACPI_STATUS (Status);975}976}977978/* Check special names like _WAK and _PTS */979980LdCheckSpecialNames (Node, Op);981982if (ForceNewScope)983{984Status = AcpiDsScopeStackPush (Node, ObjectType, WalkState);985if (ACPI_FAILURE (Status))986{987return_ACPI_STATUS (Status);988}989}990991/* Point the Node back to the original Parse node */992993Node->Op = Op;994995FinishNode:996997/* Point the parse node to the new namespace node */998999Op->Asl.Node = Node;10001001if (Op->Asl.ParseOpcode == PARSEOP_METHOD)1002{1003/*1004* Get the method argument count from "Extra" and save1005* it in the namespace node1006*/1007Node->Value = (UINT32) Op->Asl.Extra;1008}1009else if (Op->Asl.ParseOpcode == PARSEOP_EXTERNAL &&1010Node->Type == ACPI_TYPE_METHOD &&1011(Node->Flags & ANOBJ_IS_EXTERNAL))1012{1013Node->Value =1014(UINT32) Op->Asl.Child->Asl.Next->Asl.Next->Asl.Value.Integer;1015}10161017return_ACPI_STATUS (Status);1018}101910201021/*******************************************************************************1022*1023* FUNCTION: LdMatchExternType1024*1025* PARAMETERS: Type11026* Type21027*1028* RETURN: BOOLEAN1029*1030* DESCRIPTION: Match Type1 and Type2 with the assumption that one might be1031* using external types and another might be using local types.1032* This should be used to compare the types found in external1033* declarations with types found in other external declarations or1034* named object declaration. This should not be used to match two1035* object type declarations.1036*1037******************************************************************************/10381039static BOOLEAN1040LdMatchExternType (1041ACPI_OBJECT_TYPE Type1,1042ACPI_OBJECT_TYPE Type2)1043{1044BOOLEAN Type1IsLocal = Type1 > ACPI_TYPE_EXTERNAL_MAX;1045BOOLEAN Type2IsLocal = Type2 > ACPI_TYPE_EXTERNAL_MAX;1046ACPI_OBJECT_TYPE ExternalType;1047ACPI_OBJECT_TYPE LocalType;104810491050/*1051* The inputs could represent types that are local to ACPICA or types that1052* are known externally. Some local types, such as the OperationRegion1053* field units, are defined with more granularity than ACPICA local types.1054*1055* Therefore, map the local types to the external types before matching.1056*/1057if (Type1IsLocal && !Type2IsLocal)1058{1059LocalType = Type1;1060ExternalType = Type2;1061}1062else if (!Type1IsLocal && Type2IsLocal)1063{1064LocalType = Type2;1065ExternalType = Type1;1066}1067else1068{1069return (Type1 == Type2);1070}10711072switch (LocalType)1073{1074case ACPI_TYPE_LOCAL_REGION_FIELD:1075case ACPI_TYPE_LOCAL_BANK_FIELD:1076case ACPI_TYPE_LOCAL_INDEX_FIELD:10771078LocalType = ACPI_TYPE_FIELD_UNIT;1079break;10801081default:1082break;1083}10841085return (LocalType == ExternalType);1086}108710881089/*******************************************************************************1090*1091* FUNCTION: LdAnalyzeExternals1092*1093* PARAMETERS: Node - Node that represents the named object1094* Op - Named object declaring this named object1095* ExternalOpType - Type of ExternalOp1096* WalkState - Current WalkState1097*1098* RETURN: Status1099*1100* DESCRIPTION: Node and Op represents an identically named object declaration1101* that is either declared by the ASL external keyword or declared1102* by operators that declare named objects (i.e. Name, Device,1103* OperationRegion, and etc.). This function ensures that the1104* declarations do not contradict each other.1105*1106******************************************************************************/11071108static ACPI_STATUS1109LdAnalyzeExternals (1110ACPI_NAMESPACE_NODE *Node,1111ACPI_PARSE_OBJECT *Op,1112ACPI_OBJECT_TYPE ExternalOpType,1113ACPI_WALK_STATE *WalkState)1114{1115ACPI_STATUS Status = AE_OK;1116ACPI_OBJECT_TYPE ActualExternalOpType;1117ACPI_OBJECT_TYPE ActualOpType;1118ACPI_PARSE_OBJECT *ExternalOp;1119ACPI_PARSE_OBJECT *ActualOp;112011211122/*1123* The declaration represented by Node and Op must have the same type.1124* The type of the external Op is represented by ExternalOpType. However,1125* the type of the pre-existing declaration depends on whether if Op1126* is an external declaration or an actual declaration.1127*/1128if (Op->Asl.ParseOpcode == PARSEOP_EXTERNAL)1129{1130ActualExternalOpType = ExternalOpType;1131ActualOpType = Node->Type;1132}1133else1134{1135ActualExternalOpType = Node->Type;1136ActualOpType = ExternalOpType;1137}11381139if ((ActualOpType != ACPI_TYPE_ANY) &&1140(ActualExternalOpType != ACPI_TYPE_ANY) &&1141!LdMatchExternType (ActualExternalOpType, ActualOpType))1142{1143if (Op->Asl.ParseOpcode == PARSEOP_EXTERNAL &&1144Node->Op->Asl.ParseOpcode == PARSEOP_EXTERNAL)1145{1146AslDualParseOpError (ASL_WARNING,1147ASL_MSG_DUPLICATE_EXTERN_MISMATCH, Op, NULL,1148ASL_MSG_DUPLICATE_EXTERN_FOUND_HERE, Node->Op, NULL);1149}1150else1151{1152if (Op->Asl.ParseOpcode == PARSEOP_EXTERNAL &&1153Node->Op->Asl.ParseOpcode != PARSEOP_EXTERNAL)1154{1155ExternalOp = Op;1156ActualOp = Node->Op;1157}1158else1159{1160ExternalOp = Node->Op;1161ActualOp = Op;1162}1163AslDualParseOpError (ASL_WARNING,1164ASL_MSG_DECLARATION_TYPE_MISMATCH, ExternalOp, NULL,1165ASL_MSG_TYPE_MISMATCH_FOUND_HERE, ActualOp, NULL);1166}1167}11681169/* Set the object type of the external */11701171if ((Node->Flags & ANOBJ_IS_EXTERNAL) &&1172(Op->Asl.ParseOpcode != PARSEOP_EXTERNAL))1173{1174/*1175* Allow one create on an object or segment that was1176* previously declared External1177*/1178Node->Flags &= ~ANOBJ_IS_EXTERNAL;1179Node->Type = (UINT8) ActualOpType;11801181/* Just retyped a node, probably will need to open a scope */11821183if (AcpiNsOpensScope (ActualOpType))1184{1185Status = AcpiDsScopeStackPush (Node, ActualOpType, WalkState);1186if (ACPI_FAILURE (Status))1187{1188return (Status);1189}1190}11911192Status = AE_OK;1193}1194else if (!(Node->Flags & ANOBJ_IS_EXTERNAL) &&1195(Op->Asl.ParseOpcode == PARSEOP_EXTERNAL))1196{1197/*1198* Allow externals in same scope as the definition of the1199* actual object. Similar to C. Allows multiple definition1200* blocks that refer to each other in the same file.1201*/1202Status = AE_OK;1203}1204else if ((Node->Flags & ANOBJ_IS_EXTERNAL) &&1205(Op->Asl.ParseOpcode == PARSEOP_EXTERNAL) &&1206(ActualOpType == ACPI_TYPE_ANY))1207{1208/* Allow update of externals of unknown type. */12091210Node->Type = (UINT8) ActualExternalOpType;1211Status = AE_OK;1212}12131214return (Status);1215}121612171218/*******************************************************************************1219*1220* FUNCTION: LdCheckSpecialNames1221*1222* PARAMETERS: Node - Node that represents the named object1223* Op - Named object declaring this named object1224*1225* RETURN: None1226*1227* DESCRIPTION: Check if certain named objects are declared in the incorrect1228* scope. Special named objects are listed in1229* AslGbl_SpecialNamedObjects and can only be declared at the root1230* scope. _UID inside of a processor declaration must not be a1231* string.1232*1233******************************************************************************/12341235static void1236LdCheckSpecialNames (1237ACPI_NAMESPACE_NODE *Node,1238ACPI_PARSE_OBJECT *Op)1239{1240UINT32 i;124112421243for (i = 0; i < MAX_SPECIAL_NAMES; i++)1244{1245if (ACPI_COMPARE_NAMESEG(Node->Name.Ascii, AslGbl_SpecialNamedObjects[i]) &&1246Node->Parent != AcpiGbl_RootNode)1247{1248AslError (ASL_ERROR, ASL_MSG_INVALID_SPECIAL_NAME, Op, Op->Asl.ExternalName);1249return;1250}1251}12521253if (ACPI_COMPARE_NAMESEG (Node->Name.Ascii, "_UID") &&1254Node->Parent->Type == ACPI_TYPE_PROCESSOR &&1255Node->Type == ACPI_TYPE_STRING)1256{1257AslError (ASL_ERROR, ASL_MSG_INVALID_PROCESSOR_UID , Op, "found a string");1258}1259}126012611262/*******************************************************************************1263*1264* FUNCTION: LdNamespace2Begin1265*1266* PARAMETERS: ASL_WALK_CALLBACK1267*1268* RETURN: Status1269*1270* DESCRIPTION: Descending callback used during the pass 2 parse tree walk.1271* Second pass resolves some forward references.1272*1273* Notes:1274* Currently only needs to handle the Alias operator.1275* Could be used to allow forward references from the Scope() operator, but1276* the MS interpreter does not allow this, so this compiler does not either.1277*1278******************************************************************************/12791280static ACPI_STATUS1281LdNamespace2Begin (1282ACPI_PARSE_OBJECT *Op,1283UINT32 Level,1284void *Context)1285{1286ACPI_WALK_STATE *WalkState = (ACPI_WALK_STATE *) Context;1287ACPI_STATUS Status;1288ACPI_NAMESPACE_NODE *Node;1289ACPI_OBJECT_TYPE ObjectType;1290BOOLEAN ForceNewScope = FALSE;1291ACPI_PARSE_OBJECT *Arg;1292char *Path;1293ACPI_NAMESPACE_NODE *TargetNode;129412951296ACPI_FUNCTION_NAME (LdNamespace2Begin);1297ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Op %p [%s]\n",1298Op, Op->Asl.ParseOpName));129913001301/* Ignore Ops with no namespace node */13021303Node = Op->Asl.Node;1304if (!Node)1305{1306return (AE_OK);1307}13081309/* Get the type to determine if we should push the scope */13101311if ((Op->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG) &&1312(Op->Asl.CompileFlags == OP_IS_RESOURCE_DESC))1313{1314ObjectType = ACPI_TYPE_LOCAL_RESOURCE;1315}1316else1317{1318ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode);1319}13201321/* Push scope for Resource Templates */13221323if (Op->Asl.ParseOpcode == PARSEOP_NAME)1324{1325if (Op->Asl.CompileFlags & OP_IS_RESOURCE_DESC)1326{1327ForceNewScope = TRUE;1328}1329}13301331/* Push the scope stack */13321333if (ForceNewScope || AcpiNsOpensScope (ObjectType))1334{1335Status = AcpiDsScopeStackPush (Node, ObjectType, WalkState);1336if (ACPI_FAILURE (Status))1337{1338return_ACPI_STATUS (Status);1339}1340}13411342if (Op->Asl.ParseOpcode == PARSEOP_ALIAS)1343{1344/*1345* Complete the alias node by getting and saving the target node.1346* First child is the alias target1347*/1348Arg = Op->Asl.Child;13491350/* Get the target pathname */13511352Path = Arg->Asl.Namepath;1353if (!Path)1354{1355Status = UtInternalizeName (Arg->Asl.ExternalName, &Path);1356if (ACPI_FAILURE (Status))1357{1358return (Status);1359}1360}13611362/* Get the NS node associated with the target. It must exist. */13631364Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ACPI_TYPE_ANY,1365ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE,1366WalkState, &TargetNode);1367if (ACPI_FAILURE (Status))1368{1369if (Status == AE_NOT_FOUND)1370{1371/* Standalone NameSeg vs. NamePath */13721373if (strlen (Arg->Asl.ExternalName) == ACPI_NAMESEG_SIZE)1374{1375AslError (ASL_ERROR, ASL_MSG_NOT_FOUND, Op,1376Arg->Asl.ExternalName);1377}1378else1379{1380AslError (ASL_ERROR, ASL_MSG_NAMEPATH_NOT_EXIST, Op,1381Arg->Asl.ExternalName);1382}13831384#if 01385/*1386* NOTE: Removed 10/2018 to enhance compiler error reporting. No1387* regressions seen.1388*/1389/*1390* The name was not found, go ahead and create it.1391* This prevents more errors later.1392*/1393Status = AcpiNsLookup (WalkState->ScopeInfo, Path,1394ACPI_TYPE_ANY, ACPI_IMODE_LOAD_PASS1,1395ACPI_NS_NO_UPSEARCH, WalkState, &Node);1396#endif1397return (Status);1398/* Removed: return (AE_OK)*/1399}14001401AslCoreSubsystemError (Op, Status,1402"Failure from namespace lookup", FALSE);1403return (AE_OK);1404}14051406/* Save the target node within the alias node as well as type information */14071408Node->Object = ACPI_CAST_PTR (ACPI_OPERAND_OBJECT, TargetNode);1409Node->Type = TargetNode->Type;1410if (Node->Type == ACPI_TYPE_METHOD)1411{1412/* Save the parameter count for methods */14131414Node->Value = TargetNode->Value;1415}1416}14171418return (AE_OK);1419}142014211422/*******************************************************************************1423*1424* FUNCTION: LdCommonNamespaceEnd1425*1426* PARAMETERS: ASL_WALK_CALLBACK1427*1428* RETURN: Status1429*1430* DESCRIPTION: Ascending callback used during the loading of the namespace,1431* We only need to worry about managing the scope stack here.1432*1433******************************************************************************/14341435static ACPI_STATUS1436LdCommonNamespaceEnd (1437ACPI_PARSE_OBJECT *Op,1438UINT32 Level,1439void *Context)1440{1441ACPI_WALK_STATE *WalkState = (ACPI_WALK_STATE *) Context;1442ACPI_OBJECT_TYPE ObjectType;1443BOOLEAN ForceNewScope = FALSE;144414451446ACPI_FUNCTION_NAME (LdCommonNamespaceEnd);144714481449/* We are only interested in opcodes that have an associated name */14501451if (!Op->Asl.Namepath)1452{1453return (AE_OK);1454}14551456/* Get the type to determine if we should pop the scope */14571458if ((Op->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG) &&1459(Op->Asl.CompileFlags == OP_IS_RESOURCE_DESC))1460{1461/* TBD: Merge into AcpiDsMapNamedOpcodeToDataType */14621463ObjectType = ACPI_TYPE_LOCAL_RESOURCE;1464}1465else1466{1467ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode);1468}14691470/* Pop scope that was pushed for Resource Templates */14711472if (Op->Asl.ParseOpcode == PARSEOP_NAME)1473{1474if (Op->Asl.CompileFlags & OP_IS_RESOURCE_DESC)1475{1476ForceNewScope = TRUE;1477}1478}14791480/* Pop the scope stack */14811482if (ForceNewScope || AcpiNsOpensScope (ObjectType))1483{1484ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,1485"(%s): Popping scope for Op [%s] %p\n",1486AcpiUtGetTypeName (ObjectType), Op->Asl.ParseOpName, Op));14871488(void) AcpiDsScopeStackPop (WalkState);1489}14901491return (AE_OK);1492}149314941495