1118611Snjl/****************************************************************************** 2118611Snjl * 3118611Snjl * Module Name: dswload - Dispatcher namespace load callbacks 4118611Snjl * 5118611Snjl *****************************************************************************/ 6118611Snjl 7217365Sjkim/* 8298714Sjkim * Copyright (C) 2000 - 2016, Intel Corp. 9118611Snjl * All rights reserved. 10118611Snjl * 11217365Sjkim * Redistribution and use in source and binary forms, with or without 12217365Sjkim * modification, are permitted provided that the following conditions 13217365Sjkim * are met: 14217365Sjkim * 1. Redistributions of source code must retain the above copyright 15217365Sjkim * notice, this list of conditions, and the following disclaimer, 16217365Sjkim * without modification. 17217365Sjkim * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18217365Sjkim * substantially similar to the "NO WARRANTY" disclaimer below 19217365Sjkim * ("Disclaimer") and any redistribution must be conditioned upon 20217365Sjkim * including a substantially similar Disclaimer requirement for further 21217365Sjkim * binary redistribution. 22217365Sjkim * 3. Neither the names of the above-listed copyright holders nor the names 23217365Sjkim * of any contributors may be used to endorse or promote products derived 24217365Sjkim * from this software without specific prior written permission. 25118611Snjl * 26217365Sjkim * Alternatively, this software may be distributed under the terms of the 27217365Sjkim * GNU General Public License ("GPL") version 2 as published by the Free 28217365Sjkim * Software Foundation. 29118611Snjl * 30217365Sjkim * NO WARRANTY 31217365Sjkim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32217365Sjkim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33217365Sjkim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34217365Sjkim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35217365Sjkim * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36217365Sjkim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37217365Sjkim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38217365Sjkim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39217365Sjkim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40217365Sjkim * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41217365Sjkim * POSSIBILITY OF SUCH DAMAGES. 42217365Sjkim */ 43118611Snjl 44151937Sjkim#include <contrib/dev/acpica/compiler/aslcompiler.h> 45193529Sjkim#include <contrib/dev/acpica/include/amlcode.h> 46193529Sjkim#include <contrib/dev/acpica/include/acdispat.h> 47193529Sjkim#include <contrib/dev/acpica/include/acnamesp.h> 48118611Snjl 49118611Snjl#include "aslcompiler.y.h" 50118611Snjl 51118611Snjl#define _COMPONENT ACPI_COMPILER 52118611Snjl ACPI_MODULE_NAME ("aslload") 53118611Snjl 54151937Sjkim/* Local prototypes */ 55118611Snjl 56151937Sjkimstatic ACPI_STATUS 57151937SjkimLdLoadFieldElements ( 58151937Sjkim ACPI_PARSE_OBJECT *Op, 59151937Sjkim ACPI_WALK_STATE *WalkState); 60151937Sjkim 61151937Sjkimstatic ACPI_STATUS 62151937SjkimLdLoadResourceElements ( 63151937Sjkim ACPI_PARSE_OBJECT *Op, 64151937Sjkim ACPI_WALK_STATE *WalkState); 65151937Sjkim 66151937Sjkimstatic ACPI_STATUS 67151937SjkimLdNamespace1Begin ( 68151937Sjkim ACPI_PARSE_OBJECT *Op, 69151937Sjkim UINT32 Level, 70151937Sjkim void *Context); 71151937Sjkim 72151937Sjkimstatic ACPI_STATUS 73193529SjkimLdNamespace2Begin ( 74151937Sjkim ACPI_PARSE_OBJECT *Op, 75151937Sjkim UINT32 Level, 76151937Sjkim void *Context); 77151937Sjkim 78193529Sjkimstatic ACPI_STATUS 79193529SjkimLdCommonNamespaceEnd ( 80193529Sjkim ACPI_PARSE_OBJECT *Op, 81193529Sjkim UINT32 Level, 82193529Sjkim void *Context); 83151937Sjkim 84193529Sjkim 85118611Snjl/******************************************************************************* 86118611Snjl * 87118611Snjl * FUNCTION: LdLoadNamespace 88118611Snjl * 89151937Sjkim * PARAMETERS: RootOp - Root of the parse tree 90118611Snjl * 91118611Snjl * RETURN: Status 92118611Snjl * 93118611Snjl * DESCRIPTION: Perform a walk of the parse tree that in turn loads all of the 94193529Sjkim * named ASL/AML objects into the namespace. The namespace is 95118611Snjl * constructed in order to resolve named references and references 96118611Snjl * to named fields within resource templates/descriptors. 97118611Snjl * 98118611Snjl ******************************************************************************/ 99118611Snjl 100118611SnjlACPI_STATUS 101118611SnjlLdLoadNamespace ( 102118611Snjl ACPI_PARSE_OBJECT *RootOp) 103118611Snjl{ 104118611Snjl ACPI_WALK_STATE *WalkState; 105118611Snjl 106118611Snjl 107118611Snjl /* Create a new walk state */ 108118611Snjl 109118611Snjl WalkState = AcpiDsCreateWalkState (0, NULL, NULL, NULL); 110118611Snjl if (!WalkState) 111118611Snjl { 112241973Sjkim return (AE_NO_MEMORY); 113118611Snjl } 114118611Snjl 115193529Sjkim /* Walk the entire parse tree, first pass */ 116118611Snjl 117118611Snjl TrWalkParseTree (RootOp, ASL_WALK_VISIT_TWICE, LdNamespace1Begin, 118193529Sjkim LdCommonNamespaceEnd, WalkState); 119118611Snjl 120193529Sjkim /* Second pass to handle forward references */ 121193529Sjkim 122193529Sjkim TrWalkParseTree (RootOp, ASL_WALK_VISIT_TWICE, LdNamespace2Begin, 123193529Sjkim LdCommonNamespaceEnd, WalkState); 124193529Sjkim 125118611Snjl /* Dump the namespace if debug is enabled */ 126118611Snjl 127118611Snjl AcpiNsDumpTables (ACPI_NS_ALL, ACPI_UINT32_MAX); 128272444Sjkim ACPI_FREE (WalkState); 129241973Sjkim return (AE_OK); 130118611Snjl} 131118611Snjl 132118611Snjl 133118611Snjl/******************************************************************************* 134118611Snjl * 135118611Snjl * FUNCTION: LdLoadFieldElements 136118611Snjl * 137151937Sjkim * PARAMETERS: Op - Parent node (Field) 138118611Snjl * WalkState - Current walk state 139118611Snjl * 140118611Snjl * RETURN: Status 141118611Snjl * 142118611Snjl * DESCRIPTION: Enter the named elements of the field (children of the parent) 143118611Snjl * into the namespace. 144118611Snjl * 145118611Snjl ******************************************************************************/ 146118611Snjl 147151937Sjkimstatic ACPI_STATUS 148118611SnjlLdLoadFieldElements ( 149118611Snjl ACPI_PARSE_OBJECT *Op, 150118611Snjl ACPI_WALK_STATE *WalkState) 151118611Snjl{ 152118611Snjl ACPI_PARSE_OBJECT *Child = NULL; 153118611Snjl ACPI_NAMESPACE_NODE *Node; 154118611Snjl ACPI_STATUS Status; 155118611Snjl 156118611Snjl 157118611Snjl /* Get the first named field element */ 158118611Snjl 159118611Snjl switch (Op->Asl.AmlOpcode) 160118611Snjl { 161118611Snjl case AML_BANK_FIELD_OP: 162118611Snjl 163118611Snjl Child = UtGetArg (Op, 6); 164118611Snjl break; 165118611Snjl 166118611Snjl case AML_INDEX_FIELD_OP: 167118611Snjl 168118611Snjl Child = UtGetArg (Op, 5); 169118611Snjl break; 170118611Snjl 171118611Snjl case AML_FIELD_OP: 172118611Snjl 173118611Snjl Child = UtGetArg (Op, 4); 174118611Snjl break; 175118611Snjl 176118611Snjl default: 177250838Sjkim 178118611Snjl /* No other opcodes should arrive here */ 179250838Sjkim 180118611Snjl return (AE_BAD_PARAMETER); 181118611Snjl } 182118611Snjl 183118611Snjl /* Enter all elements into the namespace */ 184118611Snjl 185118611Snjl while (Child) 186118611Snjl { 187118611Snjl switch (Child->Asl.AmlOpcode) 188118611Snjl { 189118611Snjl case AML_INT_RESERVEDFIELD_OP: 190118611Snjl case AML_INT_ACCESSFIELD_OP: 191228110Sjkim case AML_INT_CONNECTION_OP: 192118611Snjl break; 193118611Snjl 194118611Snjl default: 195118611Snjl 196151937Sjkim Status = AcpiNsLookup (WalkState->ScopeInfo, 197298714Sjkim Child->Asl.Value.String, 198298714Sjkim ACPI_TYPE_LOCAL_REGION_FIELD, 199298714Sjkim ACPI_IMODE_LOAD_PASS1, 200298714Sjkim ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE | 201298714Sjkim ACPI_NS_ERROR_IF_FOUND, NULL, &Node); 202118611Snjl if (ACPI_FAILURE (Status)) 203118611Snjl { 204118611Snjl if (Status != AE_ALREADY_EXISTS) 205118611Snjl { 206151937Sjkim AslError (ASL_ERROR, ASL_MSG_CORE_EXCEPTION, Child, 207151937Sjkim Child->Asl.Value.String); 208151937Sjkim return (Status); 209118611Snjl } 210118611Snjl 211118611Snjl /* 212118611Snjl * The name already exists in this scope 213118611Snjl * But continue processing the elements 214118611Snjl */ 215151937Sjkim AslError (ASL_ERROR, ASL_MSG_NAME_EXISTS, Child, 216151937Sjkim Child->Asl.Value.String); 217118611Snjl } 218118611Snjl else 219118611Snjl { 220118611Snjl Child->Asl.Node = Node; 221151937Sjkim Node->Op = Child; 222118611Snjl } 223118611Snjl break; 224118611Snjl } 225228110Sjkim 226118611Snjl Child = Child->Asl.Next; 227118611Snjl } 228228110Sjkim 229118611Snjl return (AE_OK); 230118611Snjl} 231118611Snjl 232118611Snjl 233118611Snjl/******************************************************************************* 234118611Snjl * 235118611Snjl * FUNCTION: LdLoadResourceElements 236118611Snjl * 237151937Sjkim * PARAMETERS: Op - Parent node (Resource Descriptor) 238118611Snjl * WalkState - Current walk state 239118611Snjl * 240118611Snjl * RETURN: Status 241118611Snjl * 242118611Snjl * DESCRIPTION: Enter the named elements of the resource descriptor (children 243118611Snjl * of the parent) into the namespace. 244118611Snjl * 245193529Sjkim * NOTE: In the real AML namespace, these named elements never exist. But 246118611Snjl * we simply use the namespace here as a symbol table so we can look 247118611Snjl * them up as they are referenced. 248118611Snjl * 249118611Snjl ******************************************************************************/ 250118611Snjl 251151937Sjkimstatic ACPI_STATUS 252118611SnjlLdLoadResourceElements ( 253118611Snjl ACPI_PARSE_OBJECT *Op, 254118611Snjl ACPI_WALK_STATE *WalkState) 255118611Snjl{ 256118611Snjl ACPI_PARSE_OBJECT *InitializerOp = NULL; 257118611Snjl ACPI_NAMESPACE_NODE *Node; 258118611Snjl ACPI_STATUS Status; 259118611Snjl 260118611Snjl 261118611Snjl /* 262151937Sjkim * Enter the resource name into the namespace. Name must not already exist. 263151937Sjkim * This opens a scope, so later field names are guaranteed to be new/unique. 264118611Snjl */ 265118611Snjl Status = AcpiNsLookup (WalkState->ScopeInfo, Op->Asl.Namepath, 266298714Sjkim ACPI_TYPE_LOCAL_RESOURCE, ACPI_IMODE_LOAD_PASS1, 267298714Sjkim ACPI_NS_NO_UPSEARCH | ACPI_NS_ERROR_IF_FOUND, 268298714Sjkim WalkState, &Node); 269118611Snjl if (ACPI_FAILURE (Status)) 270118611Snjl { 271151937Sjkim if (Status == AE_ALREADY_EXISTS) 272151937Sjkim { 273151937Sjkim /* Actual node causing the error was saved in ParentMethod */ 274151937Sjkim 275151937Sjkim AslError (ASL_ERROR, ASL_MSG_NAME_EXISTS, 276151937Sjkim (ACPI_PARSE_OBJECT *) Op->Asl.ParentMethod, Op->Asl.Namepath); 277151937Sjkim return (AE_OK); 278151937Sjkim } 279118611Snjl return (Status); 280118611Snjl } 281118611Snjl 282167802Sjkim Node->Value = (UINT32) Op->Asl.Value.Integer; 283167802Sjkim Node->Op = Op; 284197104Sjkim Op->Asl.Node = Node; 285167802Sjkim 286118611Snjl /* 287118611Snjl * Now enter the predefined fields, for easy lookup when referenced 288118611Snjl * by the source ASL 289118611Snjl */ 290118611Snjl InitializerOp = ASL_GET_CHILD_NODE (Op); 291118611Snjl while (InitializerOp) 292118611Snjl { 293118611Snjl if (InitializerOp->Asl.ExternalName) 294118611Snjl { 295118611Snjl Status = AcpiNsLookup (WalkState->ScopeInfo, 296298714Sjkim InitializerOp->Asl.ExternalName, 297298714Sjkim ACPI_TYPE_LOCAL_RESOURCE_FIELD, 298298714Sjkim ACPI_IMODE_LOAD_PASS1, 299298714Sjkim ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE, 300298714Sjkim NULL, &Node); 301118611Snjl if (ACPI_FAILURE (Status)) 302118611Snjl { 303118611Snjl return (Status); 304118611Snjl } 305118611Snjl 306118611Snjl /* 307228110Sjkim * Store the field offset and length in the namespace node 308228110Sjkim * so it can be used when the field is referenced 309118611Snjl */ 310228110Sjkim Node->Value = InitializerOp->Asl.Value.Tag.BitOffset; 311228110Sjkim Node->Length = InitializerOp->Asl.Value.Tag.BitLength; 312118611Snjl InitializerOp->Asl.Node = Node; 313151937Sjkim Node->Op = InitializerOp; 314228110Sjkim } 315118611Snjl 316118611Snjl InitializerOp = ASL_GET_PEER_NODE (InitializerOp); 317118611Snjl } 318118611Snjl 319118611Snjl return (AE_OK); 320118611Snjl} 321118611Snjl 322118611Snjl 323118611Snjl/******************************************************************************* 324118611Snjl * 325118611Snjl * FUNCTION: LdNamespace1Begin 326118611Snjl * 327118611Snjl * PARAMETERS: ASL_WALK_CALLBACK 328118611Snjl * 329118611Snjl * RETURN: Status 330118611Snjl * 331193529Sjkim * DESCRIPTION: Descending callback used during the parse tree walk. If this 332118611Snjl * is a named AML opcode, enter into the namespace 333118611Snjl * 334118611Snjl ******************************************************************************/ 335118611Snjl 336151937Sjkimstatic ACPI_STATUS 337118611SnjlLdNamespace1Begin ( 338118611Snjl ACPI_PARSE_OBJECT *Op, 339118611Snjl UINT32 Level, 340118611Snjl void *Context) 341118611Snjl{ 342118611Snjl ACPI_WALK_STATE *WalkState = (ACPI_WALK_STATE *) Context; 343118611Snjl ACPI_NAMESPACE_NODE *Node; 344298714Sjkim ACPI_PARSE_OBJECT *MethodOp; 345118611Snjl ACPI_STATUS Status; 346118611Snjl ACPI_OBJECT_TYPE ObjectType; 347118611Snjl ACPI_OBJECT_TYPE ActualObjectType = ACPI_TYPE_ANY; 348118611Snjl char *Path; 349118611Snjl UINT32 Flags = ACPI_NS_NO_UPSEARCH; 350118611Snjl ACPI_PARSE_OBJECT *Arg; 351118611Snjl UINT32 i; 352167802Sjkim BOOLEAN ForceNewScope = FALSE; 353118611Snjl 354118611Snjl 355167802Sjkim ACPI_FUNCTION_NAME (LdNamespace1Begin); 356118611Snjl ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Op %p [%s]\n", 357118611Snjl Op, Op->Asl.ParseOpName)); 358118611Snjl 359118611Snjl /* 360118611Snjl * We are only interested in opcodes that have an associated name 361118611Snjl * (or multiple names) 362118611Snjl */ 363118611Snjl switch (Op->Asl.AmlOpcode) 364118611Snjl { 365118611Snjl case AML_BANK_FIELD_OP: 366118611Snjl case AML_INDEX_FIELD_OP: 367118611Snjl case AML_FIELD_OP: 368118611Snjl 369118611Snjl Status = LdLoadFieldElements (Op, WalkState); 370118611Snjl return (Status); 371118611Snjl 372272444Sjkim case AML_INT_CONNECTION_OP: 373272444Sjkim 374272444Sjkim 375272444Sjkim if (Op->Asl.Child->Asl.AmlOpcode != AML_INT_NAMEPATH_OP) 376272444Sjkim { 377272444Sjkim break; 378272444Sjkim } 379272444Sjkim Arg = Op->Asl.Child; 380272444Sjkim 381272444Sjkim Status = AcpiNsLookup (WalkState->ScopeInfo, Arg->Asl.ExternalName, 382272444Sjkim ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT, 383272444Sjkim WalkState, &Node); 384272444Sjkim if (ACPI_FAILURE (Status)) 385272444Sjkim { 386272444Sjkim break; 387272444Sjkim } 388272444Sjkim 389272444Sjkim if (Node->Type == ACPI_TYPE_BUFFER) 390272444Sjkim { 391272444Sjkim Arg->Asl.Node = Node; 392272444Sjkim 393272444Sjkim Arg = Node->Op->Asl.Child; /* Get namepath */ 394272444Sjkim Arg = Arg->Asl.Next; /* Get actual buffer */ 395272444Sjkim Arg = Arg->Asl.Child; /* Buffer length */ 396272444Sjkim Arg = Arg->Asl.Next; /* RAW_DATA buffer */ 397272444Sjkim } 398272444Sjkim break; 399272444Sjkim 400118611Snjl default: 401118611Snjl 402118611Snjl /* All other opcodes go below */ 403250838Sjkim 404118611Snjl break; 405118611Snjl } 406118611Snjl 407118611Snjl /* Check if this object has already been installed in the namespace */ 408118611Snjl 409118611Snjl if (Op->Asl.Node) 410118611Snjl { 411118611Snjl return (AE_OK); 412118611Snjl } 413118611Snjl 414118611Snjl Path = Op->Asl.Namepath; 415118611Snjl if (!Path) 416118611Snjl { 417118611Snjl return (AE_OK); 418118611Snjl } 419118611Snjl 420118611Snjl /* Map the raw opcode into an internal object type */ 421118611Snjl 422118611Snjl switch (Op->Asl.ParseOpcode) 423118611Snjl { 424118611Snjl case PARSEOP_NAME: 425118611Snjl 426151937Sjkim Arg = Op->Asl.Child; /* Get the NameSeg/NameString node */ 427151937Sjkim Arg = Arg->Asl.Next; /* First peer is the object to be associated with the name */ 428118611Snjl 429167802Sjkim /* 430167802Sjkim * If this name refers to a ResourceTemplate, we will need to open 431167802Sjkim * a new scope so that the resource subfield names can be entered into 432167802Sjkim * the namespace underneath this name 433167802Sjkim */ 434167802Sjkim if (Op->Asl.CompileFlags & NODE_IS_RESOURCE_DESC) 435167802Sjkim { 436167802Sjkim ForceNewScope = TRUE; 437167802Sjkim } 438167802Sjkim 439118611Snjl /* Get the data type associated with the named object, not the name itself */ 440118611Snjl 441118611Snjl /* Log2 loop to convert from Btype (binary) to Etype (encoded) */ 442118611Snjl 443118611Snjl ObjectType = 1; 444118611Snjl for (i = 1; i < Arg->Asl.AcpiBtype; i *= 2) 445118611Snjl { 446118611Snjl ObjectType++; 447118611Snjl } 448118611Snjl break; 449118611Snjl 450118611Snjl 451118611Snjl case PARSEOP_EXTERNAL: 452118611Snjl /* 453118611Snjl * "External" simply enters a name and type into the namespace. 454118611Snjl * We must be careful to not open a new scope, however, no matter 455118611Snjl * what type the external name refers to (e.g., a method) 456118611Snjl * 457118611Snjl * first child is name, next child is ObjectType 458118611Snjl */ 459118611Snjl ActualObjectType = (UINT8) Op->Asl.Child->Asl.Next->Asl.Value.Integer; 460118611Snjl ObjectType = ACPI_TYPE_ANY; 461167802Sjkim 462167802Sjkim /* 463167802Sjkim * We will mark every new node along the path as "External". This 464167802Sjkim * allows some or all of the nodes to be created later in the ASL 465167802Sjkim * code. Handles cases like this: 466167802Sjkim * 467167802Sjkim * External (\_SB_.PCI0.ABCD, IntObj) 468167802Sjkim * Scope (_SB_) 469167802Sjkim * { 470167802Sjkim * Device (PCI0) 471167802Sjkim * { 472167802Sjkim * } 473167802Sjkim * } 474167802Sjkim * Method (X) 475167802Sjkim * { 476167802Sjkim * Store (\_SB_.PCI0.ABCD, Local0) 477167802Sjkim * } 478167802Sjkim */ 479167802Sjkim Flags |= ACPI_NS_EXTERNAL; 480118611Snjl break; 481118611Snjl 482118611Snjl case PARSEOP_DEFAULT_ARG: 483118611Snjl 484167802Sjkim if (Op->Asl.CompileFlags == NODE_IS_RESOURCE_DESC) 485118611Snjl { 486118611Snjl Status = LdLoadResourceElements (Op, WalkState); 487202771Sjkim return_ACPI_STATUS (Status); 488118611Snjl } 489118611Snjl 490118611Snjl ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode); 491118611Snjl break; 492118611Snjl 493118611Snjl case PARSEOP_SCOPE: 494118611Snjl /* 495118611Snjl * The name referenced by Scope(Name) must already exist at this point. 496118611Snjl * In other words, forward references for Scope() are not supported. 497118611Snjl * The only real reason for this is that the MS interpreter cannot 498193529Sjkim * handle this case. Perhaps someday this case can go away. 499118611Snjl */ 500118611Snjl Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ACPI_TYPE_ANY, 501298714Sjkim ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT, 502298714Sjkim WalkState, &(Node)); 503118611Snjl if (ACPI_FAILURE (Status)) 504118611Snjl { 505118611Snjl if (Status == AE_NOT_FOUND) 506118611Snjl { 507118611Snjl /* The name was not found, go ahead and create it */ 508118611Snjl 509151937Sjkim Status = AcpiNsLookup (WalkState->ScopeInfo, Path, 510298714Sjkim ACPI_TYPE_LOCAL_SCOPE, 511298714Sjkim ACPI_IMODE_LOAD_PASS1, Flags, 512298714Sjkim WalkState, &(Node)); 513254745Sjkim if (ACPI_FAILURE (Status)) 514254745Sjkim { 515254745Sjkim return_ACPI_STATUS (Status); 516254745Sjkim } 517118611Snjl 518118611Snjl /* 519118611Snjl * However, this is an error -- primarily because the MS 520118611Snjl * interpreter can't handle a forward reference from the 521118611Snjl * Scope() operator. 522118611Snjl */ 523151937Sjkim AslError (ASL_ERROR, ASL_MSG_NOT_FOUND, Op, 524151937Sjkim Op->Asl.ExternalName); 525151937Sjkim AslError (ASL_ERROR, ASL_MSG_SCOPE_FWD_REF, Op, 526151937Sjkim Op->Asl.ExternalName); 527118611Snjl goto FinishNode; 528118611Snjl } 529118611Snjl 530198237Sjkim AslCoreSubsystemError (Op, Status, 531198237Sjkim "Failure from namespace lookup", FALSE); 532198237Sjkim 533202771Sjkim return_ACPI_STATUS (Status); 534118611Snjl } 535298714Sjkim else /* Status AE_OK */ 536298714Sjkim { 537298714Sjkim /* 538298714Sjkim * Do not allow references to external scopes from the DSDT. 539298714Sjkim * This is because the DSDT is always loaded first, and the 540298714Sjkim * external reference cannot be resolved -- causing a runtime 541298714Sjkim * error because Scope() must be resolved immediately. 542298714Sjkim * 10/2015. 543298714Sjkim */ 544298714Sjkim if ((Node->Flags & ANOBJ_IS_EXTERNAL) && 545298714Sjkim (ACPI_COMPARE_NAME (Gbl_TableSignature, "DSDT"))) 546298714Sjkim { 547298714Sjkim /* However, allowed if the reference is within a method */ 548118611Snjl 549298714Sjkim MethodOp = Op->Asl.Parent; 550298714Sjkim while (MethodOp && 551298714Sjkim (MethodOp->Asl.ParseOpcode != PARSEOP_METHOD)) 552298714Sjkim { 553298714Sjkim MethodOp = MethodOp->Asl.Parent; 554298714Sjkim } 555298714Sjkim 556298714Sjkim if (!MethodOp) 557298714Sjkim { 558298714Sjkim /* Not in a control method, error */ 559298714Sjkim 560298714Sjkim AslError (ASL_ERROR, ASL_MSG_CROSS_TABLE_SCOPE, Op, NULL); 561298714Sjkim } 562298714Sjkim } 563298714Sjkim } 564298714Sjkim 565118611Snjl /* We found a node with this name, now check the type */ 566118611Snjl 567118611Snjl switch (Node->Type) 568118611Snjl { 569118611Snjl case ACPI_TYPE_LOCAL_SCOPE: 570118611Snjl case ACPI_TYPE_DEVICE: 571118611Snjl case ACPI_TYPE_POWER: 572118611Snjl case ACPI_TYPE_PROCESSOR: 573118611Snjl case ACPI_TYPE_THERMAL: 574118611Snjl 575118611Snjl /* These are acceptable types - they all open a new scope */ 576118611Snjl break; 577118611Snjl 578118611Snjl case ACPI_TYPE_INTEGER: 579118611Snjl case ACPI_TYPE_STRING: 580118611Snjl case ACPI_TYPE_BUFFER: 581118611Snjl /* 582151937Sjkim * These types we will allow, but we will change the type. 583151937Sjkim * This enables some existing code of the form: 584118611Snjl * 585118611Snjl * Name (DEB, 0) 586118611Snjl * Scope (DEB) { ... } 587118611Snjl * 588118611Snjl * Which is used to workaround the fact that the MS interpreter 589118611Snjl * does not allow Scope() forward references. 590118611Snjl */ 591128212Snjl sprintf (MsgBuffer, "%s [%s], changing type to [Scope]", 592118611Snjl Op->Asl.ExternalName, AcpiUtGetTypeName (Node->Type)); 593118611Snjl AslError (ASL_REMARK, ASL_MSG_SCOPE_TYPE, Op, MsgBuffer); 594118611Snjl 595151937Sjkim /* Switch the type to scope, open the new scope */ 596151937Sjkim 597128212Snjl Node->Type = ACPI_TYPE_LOCAL_SCOPE; 598151937Sjkim Status = AcpiDsScopeStackPush (Node, ACPI_TYPE_LOCAL_SCOPE, 599298714Sjkim WalkState); 600128212Snjl if (ACPI_FAILURE (Status)) 601128212Snjl { 602128212Snjl return_ACPI_STATUS (Status); 603128212Snjl } 604118611Snjl break; 605118611Snjl 606118611Snjl default: 607118611Snjl 608151937Sjkim /* All other types are an error */ 609151937Sjkim 610151937Sjkim sprintf (MsgBuffer, "%s [%s]", Op->Asl.ExternalName, 611151937Sjkim AcpiUtGetTypeName (Node->Type)); 612118611Snjl AslError (ASL_ERROR, ASL_MSG_SCOPE_TYPE, Op, MsgBuffer); 613118611Snjl 614118611Snjl /* 615118611Snjl * However, switch the type to be an actual scope so 616118611Snjl * that compilation can continue without generating a whole 617193529Sjkim * cascade of additional errors. Open the new scope. 618118611Snjl */ 619128212Snjl Node->Type = ACPI_TYPE_LOCAL_SCOPE; 620151937Sjkim Status = AcpiDsScopeStackPush (Node, ACPI_TYPE_LOCAL_SCOPE, 621298714Sjkim WalkState); 622128212Snjl if (ACPI_FAILURE (Status)) 623128212Snjl { 624128212Snjl return_ACPI_STATUS (Status); 625128212Snjl } 626118611Snjl break; 627118611Snjl } 628118611Snjl 629118611Snjl Status = AE_OK; 630118611Snjl goto FinishNode; 631118611Snjl 632118611Snjl 633118611Snjl default: 634118611Snjl 635118611Snjl ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode); 636118611Snjl break; 637118611Snjl } 638118611Snjl 639118611Snjl 640118611Snjl ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Loading name: %s, (%s)\n", 641298714Sjkim Op->Asl.ExternalName, AcpiUtGetTypeName (ObjectType))); 642118611Snjl 643118611Snjl /* The name must not already exist */ 644118611Snjl 645118611Snjl Flags |= ACPI_NS_ERROR_IF_FOUND; 646118611Snjl 647118611Snjl /* 648193529Sjkim * Enter the named type into the internal namespace. We enter the name 649193529Sjkim * as we go downward in the parse tree. Any necessary subobjects that 650151937Sjkim * involve arguments to the opcode must be created as we go back up the 651151937Sjkim * parse tree later. 652118611Snjl */ 653118611Snjl Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ObjectType, 654298714Sjkim ACPI_IMODE_LOAD_PASS1, Flags, WalkState, &Node); 655118611Snjl if (ACPI_FAILURE (Status)) 656118611Snjl { 657118611Snjl if (Status == AE_ALREADY_EXISTS) 658118611Snjl { 659118611Snjl /* The name already exists in this scope */ 660118611Snjl 661118611Snjl if (Node->Type == ACPI_TYPE_LOCAL_SCOPE) 662118611Snjl { 663167802Sjkim /* Allow multiple references to the same scope */ 664167802Sjkim 665118611Snjl Node->Type = (UINT8) ObjectType; 666118611Snjl Status = AE_OK; 667118611Snjl } 668193529Sjkim else if ((Node->Flags & ANOBJ_IS_EXTERNAL) && 669193529Sjkim (Op->Asl.ParseOpcode != PARSEOP_EXTERNAL)) 670167802Sjkim { 671167802Sjkim /* 672167802Sjkim * Allow one create on an object or segment that was 673167802Sjkim * previously declared External 674167802Sjkim */ 675167802Sjkim Node->Flags &= ~ANOBJ_IS_EXTERNAL; 676167802Sjkim Node->Type = (UINT8) ObjectType; 677167802Sjkim 678167802Sjkim /* Just retyped a node, probably will need to open a scope */ 679167802Sjkim 680167802Sjkim if (AcpiNsOpensScope (ObjectType)) 681167802Sjkim { 682167802Sjkim Status = AcpiDsScopeStackPush (Node, ObjectType, WalkState); 683167802Sjkim if (ACPI_FAILURE (Status)) 684167802Sjkim { 685167802Sjkim return_ACPI_STATUS (Status); 686167802Sjkim } 687167802Sjkim } 688298714Sjkim 689167802Sjkim Status = AE_OK; 690167802Sjkim } 691298714Sjkim else if (!(Node->Flags & ANOBJ_IS_EXTERNAL) && 692298714Sjkim (Op->Asl.ParseOpcode == PARSEOP_EXTERNAL)) 693298714Sjkim { 694298714Sjkim /* 695298714Sjkim * Allow externals in same scope as the definition of the 696298714Sjkim * actual object. Similar to C. Allows multiple definition 697298714Sjkim * blocks that refer to each other in the same file. 698298714Sjkim */ 699298714Sjkim Status = AE_OK; 700298714Sjkim } 701298714Sjkim else if ((Node->Flags & ANOBJ_IS_EXTERNAL) && 702298714Sjkim (Op->Asl.ParseOpcode == PARSEOP_EXTERNAL) && 703298714Sjkim (ObjectType == ACPI_TYPE_ANY)) 704298714Sjkim { 705298714Sjkim /* Allow update of externals of unknown type. */ 706298714Sjkim 707298714Sjkim if (AcpiNsOpensScope (ActualObjectType)) 708298714Sjkim { 709298714Sjkim Node->Type = (UINT8) ActualObjectType; 710298714Sjkim Status = AE_OK; 711298714Sjkim } 712298714Sjkim else 713298714Sjkim { 714298714Sjkim sprintf (MsgBuffer, "%s [%s]", Op->Asl.ExternalName, 715298714Sjkim AcpiUtGetTypeName (Node->Type)); 716298714Sjkim AslError (ASL_ERROR, ASL_MSG_SCOPE_TYPE, Op, MsgBuffer); 717298714Sjkim return_ACPI_STATUS (AE_OK); 718298714Sjkim } 719298714Sjkim } 720118611Snjl else 721118611Snjl { 722167802Sjkim /* Valid error, object already exists */ 723167802Sjkim 724151937Sjkim AslError (ASL_ERROR, ASL_MSG_NAME_EXISTS, Op, 725151937Sjkim Op->Asl.ExternalName); 726202771Sjkim return_ACPI_STATUS (AE_OK); 727118611Snjl } 728118611Snjl } 729118611Snjl else 730118611Snjl { 731151937Sjkim AslCoreSubsystemError (Op, Status, 732198237Sjkim "Failure from namespace lookup", FALSE); 733202771Sjkim return_ACPI_STATUS (Status); 734118611Snjl } 735118611Snjl } 736118611Snjl 737167802Sjkim if (ForceNewScope) 738167802Sjkim { 739167802Sjkim Status = AcpiDsScopeStackPush (Node, ObjectType, WalkState); 740167802Sjkim if (ACPI_FAILURE (Status)) 741167802Sjkim { 742167802Sjkim return_ACPI_STATUS (Status); 743167802Sjkim } 744167802Sjkim } 745118611Snjl 746118611SnjlFinishNode: 747118611Snjl /* 748118611Snjl * Point the parse node to the new namespace node, and point 749118611Snjl * the Node back to the original Parse node 750118611Snjl */ 751118611Snjl Op->Asl.Node = Node; 752151937Sjkim Node->Op = Op; 753118611Snjl 754118611Snjl /* Set the actual data type if appropriate (EXTERNAL term only) */ 755118611Snjl 756118611Snjl if (ActualObjectType != ACPI_TYPE_ANY) 757118611Snjl { 758118611Snjl Node->Type = (UINT8) ActualObjectType; 759151937Sjkim Node->Value = ASL_EXTERNAL_METHOD; 760118611Snjl } 761118611Snjl 762118611Snjl if (Op->Asl.ParseOpcode == PARSEOP_METHOD) 763118611Snjl { 764118611Snjl /* 765151937Sjkim * Get the method argument count from "Extra" and save 766151937Sjkim * it in the namespace node 767118611Snjl */ 768151937Sjkim Node->Value = (UINT32) Op->Asl.Extra; 769118611Snjl } 770118611Snjl 771202771Sjkim return_ACPI_STATUS (Status); 772118611Snjl} 773118611Snjl 774118611Snjl 775118611Snjl/******************************************************************************* 776118611Snjl * 777193529Sjkim * FUNCTION: LdNamespace2Begin 778118611Snjl * 779118611Snjl * PARAMETERS: ASL_WALK_CALLBACK 780118611Snjl * 781118611Snjl * RETURN: Status 782118611Snjl * 783193529Sjkim * DESCRIPTION: Descending callback used during the pass 2 parse tree walk. 784193529Sjkim * Second pass resolves some forward references. 785193529Sjkim * 786193529Sjkim * Notes: 787193529Sjkim * Currently only needs to handle the Alias operator. 788193529Sjkim * Could be used to allow forward references from the Scope() operator, but 789193529Sjkim * the MS interpreter does not allow this, so this compiler does not either. 790193529Sjkim * 791193529Sjkim ******************************************************************************/ 792193529Sjkim 793193529Sjkimstatic ACPI_STATUS 794193529SjkimLdNamespace2Begin ( 795193529Sjkim ACPI_PARSE_OBJECT *Op, 796193529Sjkim UINT32 Level, 797193529Sjkim void *Context) 798193529Sjkim{ 799193529Sjkim ACPI_WALK_STATE *WalkState = (ACPI_WALK_STATE *) Context; 800193529Sjkim ACPI_STATUS Status; 801193529Sjkim ACPI_NAMESPACE_NODE *Node; 802193529Sjkim ACPI_OBJECT_TYPE ObjectType; 803193529Sjkim BOOLEAN ForceNewScope = FALSE; 804193529Sjkim ACPI_PARSE_OBJECT *Arg; 805193529Sjkim char *Path; 806193529Sjkim ACPI_NAMESPACE_NODE *TargetNode; 807193529Sjkim 808193529Sjkim 809193529Sjkim ACPI_FUNCTION_NAME (LdNamespace2Begin); 810193529Sjkim ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Op %p [%s]\n", 811193529Sjkim Op, Op->Asl.ParseOpName)); 812193529Sjkim 813193529Sjkim 814193529Sjkim /* Ignore Ops with no namespace node */ 815193529Sjkim 816193529Sjkim Node = Op->Asl.Node; 817193529Sjkim if (!Node) 818193529Sjkim { 819193529Sjkim return (AE_OK); 820193529Sjkim } 821193529Sjkim 822193529Sjkim /* Get the type to determine if we should push the scope */ 823193529Sjkim 824193529Sjkim if ((Op->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG) && 825193529Sjkim (Op->Asl.CompileFlags == NODE_IS_RESOURCE_DESC)) 826193529Sjkim { 827193529Sjkim ObjectType = ACPI_TYPE_LOCAL_RESOURCE; 828193529Sjkim } 829193529Sjkim else 830193529Sjkim { 831193529Sjkim ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode); 832193529Sjkim } 833193529Sjkim 834193529Sjkim /* Push scope for Resource Templates */ 835193529Sjkim 836193529Sjkim if (Op->Asl.ParseOpcode == PARSEOP_NAME) 837193529Sjkim { 838193529Sjkim if (Op->Asl.CompileFlags & NODE_IS_RESOURCE_DESC) 839193529Sjkim { 840193529Sjkim ForceNewScope = TRUE; 841193529Sjkim } 842193529Sjkim } 843193529Sjkim 844193529Sjkim /* Push the scope stack */ 845193529Sjkim 846193529Sjkim if (ForceNewScope || AcpiNsOpensScope (ObjectType)) 847193529Sjkim { 848193529Sjkim Status = AcpiDsScopeStackPush (Node, ObjectType, WalkState); 849193529Sjkim if (ACPI_FAILURE (Status)) 850193529Sjkim { 851193529Sjkim return_ACPI_STATUS (Status); 852193529Sjkim } 853193529Sjkim } 854193529Sjkim 855193529Sjkim if (Op->Asl.ParseOpcode == PARSEOP_ALIAS) 856193529Sjkim { 857193529Sjkim /* Complete the alias node by getting and saving the target node */ 858193529Sjkim 859193529Sjkim /* First child is the alias target */ 860193529Sjkim 861193529Sjkim Arg = Op->Asl.Child; 862193529Sjkim 863193529Sjkim /* Get the target pathname */ 864193529Sjkim 865193529Sjkim Path = Arg->Asl.Namepath; 866193529Sjkim if (!Path) 867193529Sjkim { 868193529Sjkim Status = UtInternalizeName (Arg->Asl.ExternalName, &Path); 869193529Sjkim if (ACPI_FAILURE (Status)) 870193529Sjkim { 871193529Sjkim return (Status); 872193529Sjkim } 873193529Sjkim } 874193529Sjkim 875193529Sjkim /* Get the NS node associated with the target. It must exist. */ 876193529Sjkim 877193529Sjkim Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ACPI_TYPE_ANY, 878298714Sjkim ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE, 879298714Sjkim WalkState, &TargetNode); 880193529Sjkim if (ACPI_FAILURE (Status)) 881193529Sjkim { 882193529Sjkim if (Status == AE_NOT_FOUND) 883193529Sjkim { 884193529Sjkim AslError (ASL_ERROR, ASL_MSG_NOT_FOUND, Op, 885193529Sjkim Op->Asl.ExternalName); 886193529Sjkim 887193529Sjkim /* 888193529Sjkim * The name was not found, go ahead and create it. 889193529Sjkim * This prevents more errors later. 890193529Sjkim */ 891193529Sjkim Status = AcpiNsLookup (WalkState->ScopeInfo, Path, 892298714Sjkim ACPI_TYPE_ANY, 893298714Sjkim ACPI_IMODE_LOAD_PASS1, ACPI_NS_NO_UPSEARCH, 894298714Sjkim WalkState, &(Node)); 895193529Sjkim return (AE_OK); 896193529Sjkim } 897193529Sjkim 898198237Sjkim AslCoreSubsystemError (Op, Status, 899198237Sjkim "Failure from namespace lookup", FALSE); 900193529Sjkim return (AE_OK); 901193529Sjkim } 902193529Sjkim 903193529Sjkim /* Save the target node within the alias node */ 904193529Sjkim 905193529Sjkim Node->Object = ACPI_CAST_PTR (ACPI_OPERAND_OBJECT, TargetNode); 906193529Sjkim } 907193529Sjkim 908193529Sjkim return (AE_OK); 909193529Sjkim} 910193529Sjkim 911193529Sjkim 912193529Sjkim/******************************************************************************* 913193529Sjkim * 914193529Sjkim * FUNCTION: LdCommonNamespaceEnd 915193529Sjkim * 916193529Sjkim * PARAMETERS: ASL_WALK_CALLBACK 917193529Sjkim * 918193529Sjkim * RETURN: Status 919193529Sjkim * 920118611Snjl * DESCRIPTION: Ascending callback used during the loading of the namespace, 921118611Snjl * We only need to worry about managing the scope stack here. 922118611Snjl * 923118611Snjl ******************************************************************************/ 924118611Snjl 925151937Sjkimstatic ACPI_STATUS 926193529SjkimLdCommonNamespaceEnd ( 927118611Snjl ACPI_PARSE_OBJECT *Op, 928118611Snjl UINT32 Level, 929118611Snjl void *Context) 930118611Snjl{ 931118611Snjl ACPI_WALK_STATE *WalkState = (ACPI_WALK_STATE *) Context; 932118611Snjl ACPI_OBJECT_TYPE ObjectType; 933167802Sjkim BOOLEAN ForceNewScope = FALSE; 934118611Snjl 935118611Snjl 936193529Sjkim ACPI_FUNCTION_NAME (LdCommonNamespaceEnd); 937118611Snjl 938118611Snjl 939118611Snjl /* We are only interested in opcodes that have an associated name */ 940118611Snjl 941118611Snjl if (!Op->Asl.Namepath) 942118611Snjl { 943118611Snjl return (AE_OK); 944118611Snjl } 945118611Snjl 946118611Snjl /* Get the type to determine if we should pop the scope */ 947118611Snjl 948118611Snjl if ((Op->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG) && 949118611Snjl (Op->Asl.CompileFlags == NODE_IS_RESOURCE_DESC)) 950118611Snjl { 951118611Snjl /* TBD: Merge into AcpiDsMapNamedOpcodeToDataType */ 952118611Snjl 953118611Snjl ObjectType = ACPI_TYPE_LOCAL_RESOURCE; 954118611Snjl } 955118611Snjl else 956118611Snjl { 957118611Snjl ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode); 958118611Snjl } 959118611Snjl 960167802Sjkim /* Pop scope that was pushed for Resource Templates */ 961167802Sjkim 962167802Sjkim if (Op->Asl.ParseOpcode == PARSEOP_NAME) 963167802Sjkim { 964167802Sjkim if (Op->Asl.CompileFlags & NODE_IS_RESOURCE_DESC) 965167802Sjkim { 966167802Sjkim ForceNewScope = TRUE; 967167802Sjkim } 968167802Sjkim } 969167802Sjkim 970118611Snjl /* Pop the scope stack */ 971118611Snjl 972167802Sjkim if (ForceNewScope || AcpiNsOpensScope (ObjectType)) 973118611Snjl { 974118611Snjl ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, 975118611Snjl "(%s): Popping scope for Op [%s] %p\n", 976118611Snjl AcpiUtGetTypeName (ObjectType), Op->Asl.ParseOpName, Op)); 977118611Snjl 978151937Sjkim (void) AcpiDsScopeStackPop (WalkState); 979118611Snjl } 980118611Snjl 981118611Snjl return (AE_OK); 982118611Snjl} 983