1118611Snjl/****************************************************************************** 2118611Snjl * 3118611Snjl * Module Name: dswload - Dispatcher namespace load callbacks 4118611Snjl * 5118611Snjl *****************************************************************************/ 6118611Snjl 7217365Sjkim/* 8245582Sjkim * Copyright (C) 2000 - 2013, 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 44118611Snjl#define __ASLLOAD_C__ 45118611Snjl 46151937Sjkim#include <contrib/dev/acpica/compiler/aslcompiler.h> 47193529Sjkim#include <contrib/dev/acpica/include/amlcode.h> 48193529Sjkim#include <contrib/dev/acpica/include/acdispat.h> 49193529Sjkim#include <contrib/dev/acpica/include/acnamesp.h> 50118611Snjl 51118611Snjl#include "aslcompiler.y.h" 52118611Snjl 53118611Snjl#define _COMPONENT ACPI_COMPILER 54118611Snjl ACPI_MODULE_NAME ("aslload") 55118611Snjl 56151937Sjkim/* Local prototypes */ 57118611Snjl 58151937Sjkimstatic ACPI_STATUS 59151937SjkimLdLoadFieldElements ( 60151937Sjkim ACPI_PARSE_OBJECT *Op, 61151937Sjkim ACPI_WALK_STATE *WalkState); 62151937Sjkim 63151937Sjkimstatic ACPI_STATUS 64151937SjkimLdLoadResourceElements ( 65151937Sjkim ACPI_PARSE_OBJECT *Op, 66151937Sjkim ACPI_WALK_STATE *WalkState); 67151937Sjkim 68151937Sjkimstatic ACPI_STATUS 69151937SjkimLdNamespace1Begin ( 70151937Sjkim ACPI_PARSE_OBJECT *Op, 71151937Sjkim UINT32 Level, 72151937Sjkim void *Context); 73151937Sjkim 74151937Sjkimstatic ACPI_STATUS 75193529SjkimLdNamespace2Begin ( 76151937Sjkim ACPI_PARSE_OBJECT *Op, 77151937Sjkim UINT32 Level, 78151937Sjkim void *Context); 79151937Sjkim 80193529Sjkimstatic ACPI_STATUS 81193529SjkimLdCommonNamespaceEnd ( 82193529Sjkim ACPI_PARSE_OBJECT *Op, 83193529Sjkim UINT32 Level, 84193529Sjkim void *Context); 85151937Sjkim 86193529Sjkim 87118611Snjl/******************************************************************************* 88118611Snjl * 89118611Snjl * FUNCTION: LdLoadNamespace 90118611Snjl * 91151937Sjkim * PARAMETERS: RootOp - Root of the parse tree 92118611Snjl * 93118611Snjl * RETURN: Status 94118611Snjl * 95118611Snjl * DESCRIPTION: Perform a walk of the parse tree that in turn loads all of the 96193529Sjkim * named ASL/AML objects into the namespace. The namespace is 97118611Snjl * constructed in order to resolve named references and references 98118611Snjl * to named fields within resource templates/descriptors. 99118611Snjl * 100118611Snjl ******************************************************************************/ 101118611Snjl 102118611SnjlACPI_STATUS 103118611SnjlLdLoadNamespace ( 104118611Snjl ACPI_PARSE_OBJECT *RootOp) 105118611Snjl{ 106118611Snjl ACPI_WALK_STATE *WalkState; 107118611Snjl 108118611Snjl 109118611Snjl DbgPrint (ASL_DEBUG_OUTPUT, "\nCreating namespace\n\n"); 110118611Snjl 111118611Snjl /* Create a new walk state */ 112118611Snjl 113118611Snjl WalkState = AcpiDsCreateWalkState (0, NULL, NULL, NULL); 114118611Snjl if (!WalkState) 115118611Snjl { 116241973Sjkim return (AE_NO_MEMORY); 117118611Snjl } 118118611Snjl 119193529Sjkim /* Walk the entire parse tree, first pass */ 120118611Snjl 121118611Snjl TrWalkParseTree (RootOp, ASL_WALK_VISIT_TWICE, LdNamespace1Begin, 122193529Sjkim LdCommonNamespaceEnd, WalkState); 123118611Snjl 124193529Sjkim /* Second pass to handle forward references */ 125193529Sjkim 126193529Sjkim TrWalkParseTree (RootOp, ASL_WALK_VISIT_TWICE, LdNamespace2Begin, 127193529Sjkim LdCommonNamespaceEnd, WalkState); 128193529Sjkim 129118611Snjl /* Dump the namespace if debug is enabled */ 130118611Snjl 131118611Snjl AcpiNsDumpTables (ACPI_NS_ALL, ACPI_UINT32_MAX); 132241973Sjkim return (AE_OK); 133118611Snjl} 134118611Snjl 135118611Snjl 136118611Snjl/******************************************************************************* 137118611Snjl * 138118611Snjl * FUNCTION: LdLoadFieldElements 139118611Snjl * 140151937Sjkim * PARAMETERS: Op - Parent node (Field) 141118611Snjl * WalkState - Current walk state 142118611Snjl * 143118611Snjl * RETURN: Status 144118611Snjl * 145118611Snjl * DESCRIPTION: Enter the named elements of the field (children of the parent) 146118611Snjl * into the namespace. 147118611Snjl * 148118611Snjl ******************************************************************************/ 149118611Snjl 150151937Sjkimstatic ACPI_STATUS 151118611SnjlLdLoadFieldElements ( 152118611Snjl ACPI_PARSE_OBJECT *Op, 153118611Snjl ACPI_WALK_STATE *WalkState) 154118611Snjl{ 155118611Snjl ACPI_PARSE_OBJECT *Child = NULL; 156118611Snjl ACPI_NAMESPACE_NODE *Node; 157118611Snjl ACPI_STATUS Status; 158118611Snjl 159118611Snjl 160118611Snjl /* Get the first named field element */ 161118611Snjl 162118611Snjl switch (Op->Asl.AmlOpcode) 163118611Snjl { 164118611Snjl case AML_BANK_FIELD_OP: 165118611Snjl 166118611Snjl Child = UtGetArg (Op, 6); 167118611Snjl break; 168118611Snjl 169118611Snjl case AML_INDEX_FIELD_OP: 170118611Snjl 171118611Snjl Child = UtGetArg (Op, 5); 172118611Snjl break; 173118611Snjl 174118611Snjl case AML_FIELD_OP: 175118611Snjl 176118611Snjl Child = UtGetArg (Op, 4); 177118611Snjl break; 178118611Snjl 179118611Snjl default: 180250838Sjkim 181118611Snjl /* No other opcodes should arrive here */ 182250838Sjkim 183118611Snjl return (AE_BAD_PARAMETER); 184118611Snjl } 185118611Snjl 186118611Snjl /* Enter all elements into the namespace */ 187118611Snjl 188118611Snjl while (Child) 189118611Snjl { 190118611Snjl switch (Child->Asl.AmlOpcode) 191118611Snjl { 192118611Snjl case AML_INT_RESERVEDFIELD_OP: 193118611Snjl case AML_INT_ACCESSFIELD_OP: 194228110Sjkim case AML_INT_CONNECTION_OP: 195118611Snjl break; 196118611Snjl 197118611Snjl default: 198118611Snjl 199151937Sjkim Status = AcpiNsLookup (WalkState->ScopeInfo, 200151937Sjkim Child->Asl.Value.String, 201151937Sjkim ACPI_TYPE_LOCAL_REGION_FIELD, 202151937Sjkim ACPI_IMODE_LOAD_PASS1, 203151937Sjkim ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE | 204151937Sjkim ACPI_NS_ERROR_IF_FOUND, 205151937Sjkim NULL, &Node); 206118611Snjl if (ACPI_FAILURE (Status)) 207118611Snjl { 208118611Snjl if (Status != AE_ALREADY_EXISTS) 209118611Snjl { 210151937Sjkim AslError (ASL_ERROR, ASL_MSG_CORE_EXCEPTION, Child, 211151937Sjkim Child->Asl.Value.String); 212151937Sjkim return (Status); 213118611Snjl } 214118611Snjl 215118611Snjl /* 216118611Snjl * The name already exists in this scope 217118611Snjl * But continue processing the elements 218118611Snjl */ 219151937Sjkim AslError (ASL_ERROR, ASL_MSG_NAME_EXISTS, Child, 220151937Sjkim Child->Asl.Value.String); 221118611Snjl } 222118611Snjl else 223118611Snjl { 224118611Snjl Child->Asl.Node = Node; 225151937Sjkim Node->Op = Child; 226118611Snjl } 227118611Snjl break; 228118611Snjl } 229228110Sjkim 230118611Snjl Child = Child->Asl.Next; 231118611Snjl } 232228110Sjkim 233118611Snjl return (AE_OK); 234118611Snjl} 235118611Snjl 236118611Snjl 237118611Snjl/******************************************************************************* 238118611Snjl * 239118611Snjl * FUNCTION: LdLoadResourceElements 240118611Snjl * 241151937Sjkim * PARAMETERS: Op - Parent node (Resource Descriptor) 242118611Snjl * WalkState - Current walk state 243118611Snjl * 244118611Snjl * RETURN: Status 245118611Snjl * 246118611Snjl * DESCRIPTION: Enter the named elements of the resource descriptor (children 247118611Snjl * of the parent) into the namespace. 248118611Snjl * 249193529Sjkim * NOTE: In the real AML namespace, these named elements never exist. But 250118611Snjl * we simply use the namespace here as a symbol table so we can look 251118611Snjl * them up as they are referenced. 252118611Snjl * 253118611Snjl ******************************************************************************/ 254118611Snjl 255151937Sjkimstatic ACPI_STATUS 256118611SnjlLdLoadResourceElements ( 257118611Snjl ACPI_PARSE_OBJECT *Op, 258118611Snjl ACPI_WALK_STATE *WalkState) 259118611Snjl{ 260118611Snjl ACPI_PARSE_OBJECT *InitializerOp = NULL; 261118611Snjl ACPI_NAMESPACE_NODE *Node; 262118611Snjl ACPI_STATUS Status; 263118611Snjl 264118611Snjl 265118611Snjl /* 266151937Sjkim * Enter the resource name into the namespace. Name must not already exist. 267151937Sjkim * This opens a scope, so later field names are guaranteed to be new/unique. 268118611Snjl */ 269118611Snjl Status = AcpiNsLookup (WalkState->ScopeInfo, Op->Asl.Namepath, 270151937Sjkim ACPI_TYPE_LOCAL_RESOURCE, ACPI_IMODE_LOAD_PASS1, 271151937Sjkim ACPI_NS_NO_UPSEARCH | ACPI_NS_ERROR_IF_FOUND, 272151937Sjkim WalkState, &Node); 273118611Snjl if (ACPI_FAILURE (Status)) 274118611Snjl { 275151937Sjkim if (Status == AE_ALREADY_EXISTS) 276151937Sjkim { 277151937Sjkim /* Actual node causing the error was saved in ParentMethod */ 278151937Sjkim 279151937Sjkim AslError (ASL_ERROR, ASL_MSG_NAME_EXISTS, 280151937Sjkim (ACPI_PARSE_OBJECT *) Op->Asl.ParentMethod, Op->Asl.Namepath); 281151937Sjkim return (AE_OK); 282151937Sjkim } 283118611Snjl return (Status); 284118611Snjl } 285118611Snjl 286167802Sjkim Node->Value = (UINT32) Op->Asl.Value.Integer; 287167802Sjkim Node->Op = Op; 288197104Sjkim Op->Asl.Node = Node; 289167802Sjkim 290118611Snjl /* 291118611Snjl * Now enter the predefined fields, for easy lookup when referenced 292118611Snjl * by the source ASL 293118611Snjl */ 294118611Snjl InitializerOp = ASL_GET_CHILD_NODE (Op); 295118611Snjl while (InitializerOp) 296118611Snjl { 297118611Snjl if (InitializerOp->Asl.ExternalName) 298118611Snjl { 299118611Snjl Status = AcpiNsLookup (WalkState->ScopeInfo, 300151937Sjkim InitializerOp->Asl.ExternalName, 301151937Sjkim ACPI_TYPE_LOCAL_RESOURCE_FIELD, 302151937Sjkim ACPI_IMODE_LOAD_PASS1, 303151937Sjkim ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE, 304151937Sjkim NULL, &Node); 305118611Snjl if (ACPI_FAILURE (Status)) 306118611Snjl { 307118611Snjl return (Status); 308118611Snjl } 309118611Snjl 310118611Snjl /* 311228110Sjkim * Store the field offset and length in the namespace node 312228110Sjkim * so it can be used when the field is referenced 313118611Snjl */ 314228110Sjkim Node->Value = InitializerOp->Asl.Value.Tag.BitOffset; 315228110Sjkim Node->Length = InitializerOp->Asl.Value.Tag.BitLength; 316118611Snjl InitializerOp->Asl.Node = Node; 317151937Sjkim Node->Op = InitializerOp; 318228110Sjkim } 319118611Snjl 320118611Snjl InitializerOp = ASL_GET_PEER_NODE (InitializerOp); 321118611Snjl } 322118611Snjl 323118611Snjl return (AE_OK); 324118611Snjl} 325118611Snjl 326118611Snjl 327118611Snjl/******************************************************************************* 328118611Snjl * 329118611Snjl * FUNCTION: LdNamespace1Begin 330118611Snjl * 331118611Snjl * PARAMETERS: ASL_WALK_CALLBACK 332118611Snjl * 333118611Snjl * RETURN: Status 334118611Snjl * 335193529Sjkim * DESCRIPTION: Descending callback used during the parse tree walk. If this 336118611Snjl * is a named AML opcode, enter into the namespace 337118611Snjl * 338118611Snjl ******************************************************************************/ 339118611Snjl 340151937Sjkimstatic ACPI_STATUS 341118611SnjlLdNamespace1Begin ( 342118611Snjl ACPI_PARSE_OBJECT *Op, 343118611Snjl UINT32 Level, 344118611Snjl void *Context) 345118611Snjl{ 346118611Snjl ACPI_WALK_STATE *WalkState = (ACPI_WALK_STATE *) Context; 347118611Snjl ACPI_NAMESPACE_NODE *Node; 348118611Snjl ACPI_STATUS Status; 349118611Snjl ACPI_OBJECT_TYPE ObjectType; 350118611Snjl ACPI_OBJECT_TYPE ActualObjectType = ACPI_TYPE_ANY; 351118611Snjl char *Path; 352118611Snjl UINT32 Flags = ACPI_NS_NO_UPSEARCH; 353118611Snjl ACPI_PARSE_OBJECT *Arg; 354118611Snjl UINT32 i; 355167802Sjkim BOOLEAN ForceNewScope = FALSE; 356118611Snjl 357118611Snjl 358167802Sjkim ACPI_FUNCTION_NAME (LdNamespace1Begin); 359118611Snjl ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Op %p [%s]\n", 360118611Snjl Op, Op->Asl.ParseOpName)); 361118611Snjl 362118611Snjl 363118611Snjl /* 364118611Snjl * We are only interested in opcodes that have an associated name 365118611Snjl * (or multiple names) 366118611Snjl */ 367118611Snjl switch (Op->Asl.AmlOpcode) 368118611Snjl { 369118611Snjl case AML_BANK_FIELD_OP: 370118611Snjl case AML_INDEX_FIELD_OP: 371118611Snjl case AML_FIELD_OP: 372118611Snjl 373118611Snjl Status = LdLoadFieldElements (Op, WalkState); 374118611Snjl return (Status); 375118611Snjl 376118611Snjl default: 377118611Snjl 378118611Snjl /* All other opcodes go below */ 379250838Sjkim 380118611Snjl break; 381118611Snjl } 382118611Snjl 383118611Snjl /* Check if this object has already been installed in the namespace */ 384118611Snjl 385118611Snjl if (Op->Asl.Node) 386118611Snjl { 387118611Snjl return (AE_OK); 388118611Snjl } 389118611Snjl 390118611Snjl Path = Op->Asl.Namepath; 391118611Snjl if (!Path) 392118611Snjl { 393118611Snjl return (AE_OK); 394118611Snjl } 395118611Snjl 396118611Snjl /* Map the raw opcode into an internal object type */ 397118611Snjl 398118611Snjl switch (Op->Asl.ParseOpcode) 399118611Snjl { 400118611Snjl case PARSEOP_NAME: 401118611Snjl 402151937Sjkim Arg = Op->Asl.Child; /* Get the NameSeg/NameString node */ 403151937Sjkim Arg = Arg->Asl.Next; /* First peer is the object to be associated with the name */ 404118611Snjl 405167802Sjkim /* 406167802Sjkim * If this name refers to a ResourceTemplate, we will need to open 407167802Sjkim * a new scope so that the resource subfield names can be entered into 408167802Sjkim * the namespace underneath this name 409167802Sjkim */ 410167802Sjkim if (Op->Asl.CompileFlags & NODE_IS_RESOURCE_DESC) 411167802Sjkim { 412167802Sjkim ForceNewScope = TRUE; 413167802Sjkim } 414167802Sjkim 415118611Snjl /* Get the data type associated with the named object, not the name itself */ 416118611Snjl 417118611Snjl /* Log2 loop to convert from Btype (binary) to Etype (encoded) */ 418118611Snjl 419118611Snjl ObjectType = 1; 420118611Snjl for (i = 1; i < Arg->Asl.AcpiBtype; i *= 2) 421118611Snjl { 422118611Snjl ObjectType++; 423118611Snjl } 424118611Snjl break; 425118611Snjl 426118611Snjl 427118611Snjl case PARSEOP_EXTERNAL: 428118611Snjl /* 429118611Snjl * "External" simply enters a name and type into the namespace. 430118611Snjl * We must be careful to not open a new scope, however, no matter 431118611Snjl * what type the external name refers to (e.g., a method) 432118611Snjl * 433118611Snjl * first child is name, next child is ObjectType 434118611Snjl */ 435118611Snjl ActualObjectType = (UINT8) Op->Asl.Child->Asl.Next->Asl.Value.Integer; 436118611Snjl ObjectType = ACPI_TYPE_ANY; 437167802Sjkim 438167802Sjkim /* 439167802Sjkim * We will mark every new node along the path as "External". This 440167802Sjkim * allows some or all of the nodes to be created later in the ASL 441167802Sjkim * code. Handles cases like this: 442167802Sjkim * 443167802Sjkim * External (\_SB_.PCI0.ABCD, IntObj) 444167802Sjkim * Scope (_SB_) 445167802Sjkim * { 446167802Sjkim * Device (PCI0) 447167802Sjkim * { 448167802Sjkim * } 449167802Sjkim * } 450167802Sjkim * Method (X) 451167802Sjkim * { 452167802Sjkim * Store (\_SB_.PCI0.ABCD, Local0) 453167802Sjkim * } 454167802Sjkim */ 455167802Sjkim Flags |= ACPI_NS_EXTERNAL; 456118611Snjl break; 457118611Snjl 458118611Snjl case PARSEOP_DEFAULT_ARG: 459118611Snjl 460167802Sjkim if (Op->Asl.CompileFlags == NODE_IS_RESOURCE_DESC) 461118611Snjl { 462118611Snjl Status = LdLoadResourceElements (Op, WalkState); 463202771Sjkim return_ACPI_STATUS (Status); 464118611Snjl } 465118611Snjl 466118611Snjl ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode); 467118611Snjl break; 468118611Snjl 469118611Snjl 470118611Snjl case PARSEOP_SCOPE: 471118611Snjl /* 472118611Snjl * The name referenced by Scope(Name) must already exist at this point. 473118611Snjl * In other words, forward references for Scope() are not supported. 474118611Snjl * The only real reason for this is that the MS interpreter cannot 475193529Sjkim * handle this case. Perhaps someday this case can go away. 476118611Snjl */ 477118611Snjl Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ACPI_TYPE_ANY, 478151937Sjkim ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT, 479151937Sjkim WalkState, &(Node)); 480118611Snjl if (ACPI_FAILURE (Status)) 481118611Snjl { 482118611Snjl if (Status == AE_NOT_FOUND) 483118611Snjl { 484118611Snjl /* The name was not found, go ahead and create it */ 485118611Snjl 486151937Sjkim Status = AcpiNsLookup (WalkState->ScopeInfo, Path, 487151937Sjkim ACPI_TYPE_LOCAL_SCOPE, 488151937Sjkim ACPI_IMODE_LOAD_PASS1, Flags, 489151937Sjkim WalkState, &(Node)); 490254745Sjkim if (ACPI_FAILURE (Status)) 491254745Sjkim { 492254745Sjkim return_ACPI_STATUS (Status); 493254745Sjkim } 494118611Snjl 495118611Snjl /* 496118611Snjl * However, this is an error -- primarily because the MS 497118611Snjl * interpreter can't handle a forward reference from the 498118611Snjl * Scope() operator. 499118611Snjl */ 500151937Sjkim AslError (ASL_ERROR, ASL_MSG_NOT_FOUND, Op, 501151937Sjkim Op->Asl.ExternalName); 502151937Sjkim AslError (ASL_ERROR, ASL_MSG_SCOPE_FWD_REF, Op, 503151937Sjkim Op->Asl.ExternalName); 504118611Snjl goto FinishNode; 505118611Snjl } 506118611Snjl 507198237Sjkim AslCoreSubsystemError (Op, Status, 508198237Sjkim "Failure from namespace lookup", FALSE); 509198237Sjkim 510202771Sjkim return_ACPI_STATUS (Status); 511118611Snjl } 512118611Snjl 513118611Snjl /* We found a node with this name, now check the type */ 514118611Snjl 515118611Snjl switch (Node->Type) 516118611Snjl { 517118611Snjl case ACPI_TYPE_LOCAL_SCOPE: 518118611Snjl case ACPI_TYPE_DEVICE: 519118611Snjl case ACPI_TYPE_POWER: 520118611Snjl case ACPI_TYPE_PROCESSOR: 521118611Snjl case ACPI_TYPE_THERMAL: 522118611Snjl 523118611Snjl /* These are acceptable types - they all open a new scope */ 524118611Snjl break; 525118611Snjl 526118611Snjl case ACPI_TYPE_INTEGER: 527118611Snjl case ACPI_TYPE_STRING: 528118611Snjl case ACPI_TYPE_BUFFER: 529118611Snjl /* 530151937Sjkim * These types we will allow, but we will change the type. 531151937Sjkim * This enables some existing code of the form: 532118611Snjl * 533118611Snjl * Name (DEB, 0) 534118611Snjl * Scope (DEB) { ... } 535118611Snjl * 536118611Snjl * Which is used to workaround the fact that the MS interpreter 537118611Snjl * does not allow Scope() forward references. 538118611Snjl */ 539128212Snjl sprintf (MsgBuffer, "%s [%s], changing type to [Scope]", 540118611Snjl Op->Asl.ExternalName, AcpiUtGetTypeName (Node->Type)); 541118611Snjl AslError (ASL_REMARK, ASL_MSG_SCOPE_TYPE, Op, MsgBuffer); 542118611Snjl 543151937Sjkim /* Switch the type to scope, open the new scope */ 544151937Sjkim 545128212Snjl Node->Type = ACPI_TYPE_LOCAL_SCOPE; 546151937Sjkim Status = AcpiDsScopeStackPush (Node, ACPI_TYPE_LOCAL_SCOPE, 547151937Sjkim WalkState); 548128212Snjl if (ACPI_FAILURE (Status)) 549128212Snjl { 550128212Snjl return_ACPI_STATUS (Status); 551128212Snjl } 552118611Snjl break; 553118611Snjl 554118611Snjl default: 555118611Snjl 556151937Sjkim /* All other types are an error */ 557151937Sjkim 558151937Sjkim sprintf (MsgBuffer, "%s [%s]", Op->Asl.ExternalName, 559151937Sjkim AcpiUtGetTypeName (Node->Type)); 560118611Snjl AslError (ASL_ERROR, ASL_MSG_SCOPE_TYPE, Op, MsgBuffer); 561118611Snjl 562118611Snjl /* 563118611Snjl * However, switch the type to be an actual scope so 564118611Snjl * that compilation can continue without generating a whole 565193529Sjkim * cascade of additional errors. Open the new scope. 566118611Snjl */ 567128212Snjl Node->Type = ACPI_TYPE_LOCAL_SCOPE; 568151937Sjkim Status = AcpiDsScopeStackPush (Node, ACPI_TYPE_LOCAL_SCOPE, 569151937Sjkim WalkState); 570128212Snjl if (ACPI_FAILURE (Status)) 571128212Snjl { 572128212Snjl return_ACPI_STATUS (Status); 573128212Snjl } 574118611Snjl break; 575118611Snjl } 576118611Snjl 577118611Snjl Status = AE_OK; 578118611Snjl goto FinishNode; 579118611Snjl 580118611Snjl 581118611Snjl default: 582118611Snjl 583118611Snjl ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode); 584118611Snjl break; 585118611Snjl } 586118611Snjl 587118611Snjl 588118611Snjl ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Loading name: %s, (%s)\n", 589118611Snjl Op->Asl.ExternalName, AcpiUtGetTypeName (ObjectType))); 590118611Snjl 591118611Snjl /* The name must not already exist */ 592118611Snjl 593118611Snjl Flags |= ACPI_NS_ERROR_IF_FOUND; 594118611Snjl 595118611Snjl /* 596193529Sjkim * Enter the named type into the internal namespace. We enter the name 597193529Sjkim * as we go downward in the parse tree. Any necessary subobjects that 598151937Sjkim * involve arguments to the opcode must be created as we go back up the 599151937Sjkim * parse tree later. 600118611Snjl */ 601118611Snjl Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ObjectType, 602167802Sjkim ACPI_IMODE_LOAD_PASS1, Flags, WalkState, &Node); 603118611Snjl if (ACPI_FAILURE (Status)) 604118611Snjl { 605118611Snjl if (Status == AE_ALREADY_EXISTS) 606118611Snjl { 607118611Snjl /* The name already exists in this scope */ 608118611Snjl 609118611Snjl if (Node->Type == ACPI_TYPE_LOCAL_SCOPE) 610118611Snjl { 611167802Sjkim /* Allow multiple references to the same scope */ 612167802Sjkim 613118611Snjl Node->Type = (UINT8) ObjectType; 614118611Snjl Status = AE_OK; 615118611Snjl } 616193529Sjkim else if ((Node->Flags & ANOBJ_IS_EXTERNAL) && 617193529Sjkim (Op->Asl.ParseOpcode != PARSEOP_EXTERNAL)) 618167802Sjkim { 619167802Sjkim /* 620167802Sjkim * Allow one create on an object or segment that was 621167802Sjkim * previously declared External 622167802Sjkim */ 623167802Sjkim Node->Flags &= ~ANOBJ_IS_EXTERNAL; 624167802Sjkim Node->Type = (UINT8) ObjectType; 625167802Sjkim 626167802Sjkim /* Just retyped a node, probably will need to open a scope */ 627167802Sjkim 628167802Sjkim if (AcpiNsOpensScope (ObjectType)) 629167802Sjkim { 630167802Sjkim Status = AcpiDsScopeStackPush (Node, ObjectType, WalkState); 631167802Sjkim if (ACPI_FAILURE (Status)) 632167802Sjkim { 633167802Sjkim return_ACPI_STATUS (Status); 634167802Sjkim } 635167802Sjkim } 636167802Sjkim Status = AE_OK; 637167802Sjkim } 638118611Snjl else 639118611Snjl { 640167802Sjkim /* Valid error, object already exists */ 641167802Sjkim 642151937Sjkim AslError (ASL_ERROR, ASL_MSG_NAME_EXISTS, Op, 643151937Sjkim Op->Asl.ExternalName); 644202771Sjkim return_ACPI_STATUS (AE_OK); 645118611Snjl } 646118611Snjl } 647118611Snjl else 648118611Snjl { 649151937Sjkim AslCoreSubsystemError (Op, Status, 650198237Sjkim "Failure from namespace lookup", FALSE); 651202771Sjkim return_ACPI_STATUS (Status); 652118611Snjl } 653118611Snjl } 654118611Snjl 655167802Sjkim if (ForceNewScope) 656167802Sjkim { 657167802Sjkim Status = AcpiDsScopeStackPush (Node, ObjectType, WalkState); 658167802Sjkim if (ACPI_FAILURE (Status)) 659167802Sjkim { 660167802Sjkim return_ACPI_STATUS (Status); 661167802Sjkim } 662167802Sjkim } 663118611Snjl 664118611SnjlFinishNode: 665118611Snjl /* 666118611Snjl * Point the parse node to the new namespace node, and point 667118611Snjl * the Node back to the original Parse node 668118611Snjl */ 669118611Snjl Op->Asl.Node = Node; 670151937Sjkim Node->Op = Op; 671118611Snjl 672118611Snjl /* Set the actual data type if appropriate (EXTERNAL term only) */ 673118611Snjl 674118611Snjl if (ActualObjectType != ACPI_TYPE_ANY) 675118611Snjl { 676118611Snjl Node->Type = (UINT8) ActualObjectType; 677151937Sjkim Node->Value = ASL_EXTERNAL_METHOD; 678118611Snjl } 679118611Snjl 680118611Snjl if (Op->Asl.ParseOpcode == PARSEOP_METHOD) 681118611Snjl { 682118611Snjl /* 683151937Sjkim * Get the method argument count from "Extra" and save 684151937Sjkim * it in the namespace node 685118611Snjl */ 686151937Sjkim Node->Value = (UINT32) Op->Asl.Extra; 687118611Snjl } 688118611Snjl 689202771Sjkim return_ACPI_STATUS (Status); 690118611Snjl} 691118611Snjl 692118611Snjl 693118611Snjl/******************************************************************************* 694118611Snjl * 695193529Sjkim * FUNCTION: LdNamespace2Begin 696118611Snjl * 697118611Snjl * PARAMETERS: ASL_WALK_CALLBACK 698118611Snjl * 699118611Snjl * RETURN: Status 700118611Snjl * 701193529Sjkim * DESCRIPTION: Descending callback used during the pass 2 parse tree walk. 702193529Sjkim * Second pass resolves some forward references. 703193529Sjkim * 704193529Sjkim * Notes: 705193529Sjkim * Currently only needs to handle the Alias operator. 706193529Sjkim * Could be used to allow forward references from the Scope() operator, but 707193529Sjkim * the MS interpreter does not allow this, so this compiler does not either. 708193529Sjkim * 709193529Sjkim ******************************************************************************/ 710193529Sjkim 711193529Sjkimstatic ACPI_STATUS 712193529SjkimLdNamespace2Begin ( 713193529Sjkim ACPI_PARSE_OBJECT *Op, 714193529Sjkim UINT32 Level, 715193529Sjkim void *Context) 716193529Sjkim{ 717193529Sjkim ACPI_WALK_STATE *WalkState = (ACPI_WALK_STATE *) Context; 718193529Sjkim ACPI_STATUS Status; 719193529Sjkim ACPI_NAMESPACE_NODE *Node; 720193529Sjkim ACPI_OBJECT_TYPE ObjectType; 721193529Sjkim BOOLEAN ForceNewScope = FALSE; 722193529Sjkim ACPI_PARSE_OBJECT *Arg; 723193529Sjkim char *Path; 724193529Sjkim ACPI_NAMESPACE_NODE *TargetNode; 725193529Sjkim 726193529Sjkim 727193529Sjkim ACPI_FUNCTION_NAME (LdNamespace2Begin); 728193529Sjkim ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Op %p [%s]\n", 729193529Sjkim Op, Op->Asl.ParseOpName)); 730193529Sjkim 731193529Sjkim 732193529Sjkim /* Ignore Ops with no namespace node */ 733193529Sjkim 734193529Sjkim Node = Op->Asl.Node; 735193529Sjkim if (!Node) 736193529Sjkim { 737193529Sjkim return (AE_OK); 738193529Sjkim } 739193529Sjkim 740193529Sjkim /* Get the type to determine if we should push the scope */ 741193529Sjkim 742193529Sjkim if ((Op->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG) && 743193529Sjkim (Op->Asl.CompileFlags == NODE_IS_RESOURCE_DESC)) 744193529Sjkim { 745193529Sjkim ObjectType = ACPI_TYPE_LOCAL_RESOURCE; 746193529Sjkim } 747193529Sjkim else 748193529Sjkim { 749193529Sjkim ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode); 750193529Sjkim } 751193529Sjkim 752193529Sjkim /* Push scope for Resource Templates */ 753193529Sjkim 754193529Sjkim if (Op->Asl.ParseOpcode == PARSEOP_NAME) 755193529Sjkim { 756193529Sjkim if (Op->Asl.CompileFlags & NODE_IS_RESOURCE_DESC) 757193529Sjkim { 758193529Sjkim ForceNewScope = TRUE; 759193529Sjkim } 760193529Sjkim } 761193529Sjkim 762193529Sjkim /* Push the scope stack */ 763193529Sjkim 764193529Sjkim if (ForceNewScope || AcpiNsOpensScope (ObjectType)) 765193529Sjkim { 766193529Sjkim Status = AcpiDsScopeStackPush (Node, ObjectType, WalkState); 767193529Sjkim if (ACPI_FAILURE (Status)) 768193529Sjkim { 769193529Sjkim return_ACPI_STATUS (Status); 770193529Sjkim } 771193529Sjkim } 772193529Sjkim 773193529Sjkim if (Op->Asl.ParseOpcode == PARSEOP_ALIAS) 774193529Sjkim { 775193529Sjkim /* Complete the alias node by getting and saving the target node */ 776193529Sjkim 777193529Sjkim /* First child is the alias target */ 778193529Sjkim 779193529Sjkim Arg = Op->Asl.Child; 780193529Sjkim 781193529Sjkim /* Get the target pathname */ 782193529Sjkim 783193529Sjkim Path = Arg->Asl.Namepath; 784193529Sjkim if (!Path) 785193529Sjkim { 786193529Sjkim Status = UtInternalizeName (Arg->Asl.ExternalName, &Path); 787193529Sjkim if (ACPI_FAILURE (Status)) 788193529Sjkim { 789193529Sjkim return (Status); 790193529Sjkim } 791193529Sjkim } 792193529Sjkim 793193529Sjkim /* Get the NS node associated with the target. It must exist. */ 794193529Sjkim 795193529Sjkim Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ACPI_TYPE_ANY, 796193529Sjkim ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE, 797193529Sjkim WalkState, &TargetNode); 798193529Sjkim if (ACPI_FAILURE (Status)) 799193529Sjkim { 800193529Sjkim if (Status == AE_NOT_FOUND) 801193529Sjkim { 802193529Sjkim AslError (ASL_ERROR, ASL_MSG_NOT_FOUND, Op, 803193529Sjkim Op->Asl.ExternalName); 804193529Sjkim 805193529Sjkim /* 806193529Sjkim * The name was not found, go ahead and create it. 807193529Sjkim * This prevents more errors later. 808193529Sjkim */ 809193529Sjkim Status = AcpiNsLookup (WalkState->ScopeInfo, Path, 810193529Sjkim ACPI_TYPE_ANY, 811193529Sjkim ACPI_IMODE_LOAD_PASS1, ACPI_NS_NO_UPSEARCH, 812193529Sjkim WalkState, &(Node)); 813193529Sjkim return (AE_OK); 814193529Sjkim } 815193529Sjkim 816198237Sjkim AslCoreSubsystemError (Op, Status, 817198237Sjkim "Failure from namespace lookup", FALSE); 818193529Sjkim return (AE_OK); 819193529Sjkim } 820193529Sjkim 821193529Sjkim /* Save the target node within the alias node */ 822193529Sjkim 823193529Sjkim Node->Object = ACPI_CAST_PTR (ACPI_OPERAND_OBJECT, TargetNode); 824193529Sjkim } 825193529Sjkim 826193529Sjkim return (AE_OK); 827193529Sjkim} 828193529Sjkim 829193529Sjkim 830193529Sjkim/******************************************************************************* 831193529Sjkim * 832193529Sjkim * FUNCTION: LdCommonNamespaceEnd 833193529Sjkim * 834193529Sjkim * PARAMETERS: ASL_WALK_CALLBACK 835193529Sjkim * 836193529Sjkim * RETURN: Status 837193529Sjkim * 838118611Snjl * DESCRIPTION: Ascending callback used during the loading of the namespace, 839118611Snjl * We only need to worry about managing the scope stack here. 840118611Snjl * 841118611Snjl ******************************************************************************/ 842118611Snjl 843151937Sjkimstatic ACPI_STATUS 844193529SjkimLdCommonNamespaceEnd ( 845118611Snjl ACPI_PARSE_OBJECT *Op, 846118611Snjl UINT32 Level, 847118611Snjl void *Context) 848118611Snjl{ 849118611Snjl ACPI_WALK_STATE *WalkState = (ACPI_WALK_STATE *) Context; 850118611Snjl ACPI_OBJECT_TYPE ObjectType; 851167802Sjkim BOOLEAN ForceNewScope = FALSE; 852118611Snjl 853118611Snjl 854193529Sjkim ACPI_FUNCTION_NAME (LdCommonNamespaceEnd); 855118611Snjl 856118611Snjl 857118611Snjl /* We are only interested in opcodes that have an associated name */ 858118611Snjl 859118611Snjl if (!Op->Asl.Namepath) 860118611Snjl { 861118611Snjl return (AE_OK); 862118611Snjl } 863118611Snjl 864118611Snjl /* Get the type to determine if we should pop the scope */ 865118611Snjl 866118611Snjl if ((Op->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG) && 867118611Snjl (Op->Asl.CompileFlags == NODE_IS_RESOURCE_DESC)) 868118611Snjl { 869118611Snjl /* TBD: Merge into AcpiDsMapNamedOpcodeToDataType */ 870118611Snjl 871118611Snjl ObjectType = ACPI_TYPE_LOCAL_RESOURCE; 872118611Snjl } 873118611Snjl else 874118611Snjl { 875118611Snjl ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode); 876118611Snjl } 877118611Snjl 878167802Sjkim /* Pop scope that was pushed for Resource Templates */ 879167802Sjkim 880167802Sjkim if (Op->Asl.ParseOpcode == PARSEOP_NAME) 881167802Sjkim { 882167802Sjkim if (Op->Asl.CompileFlags & NODE_IS_RESOURCE_DESC) 883167802Sjkim { 884167802Sjkim ForceNewScope = TRUE; 885167802Sjkim } 886167802Sjkim } 887167802Sjkim 888118611Snjl /* Pop the scope stack */ 889118611Snjl 890167802Sjkim if (ForceNewScope || AcpiNsOpensScope (ObjectType)) 891118611Snjl { 892118611Snjl ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, 893118611Snjl "(%s): Popping scope for Op [%s] %p\n", 894118611Snjl AcpiUtGetTypeName (ObjectType), Op->Asl.ParseOpName, Op)); 895118611Snjl 896151937Sjkim (void) AcpiDsScopeStackPop (WalkState); 897118611Snjl } 898118611Snjl 899118611Snjl return (AE_OK); 900118611Snjl} 901