aslload.c revision 193529
1118611Snjl/****************************************************************************** 2118611Snjl * 3118611Snjl * Module Name: dswload - Dispatcher namespace load callbacks 4118611Snjl * 5118611Snjl *****************************************************************************/ 6118611Snjl 7118611Snjl/****************************************************************************** 8118611Snjl * 9118611Snjl * 1. Copyright Notice 10118611Snjl * 11193529Sjkim * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. 12118611Snjl * All rights reserved. 13118611Snjl * 14118611Snjl * 2. License 15118611Snjl * 16118611Snjl * 2.1. This is your license from Intel Corp. under its intellectual property 17118611Snjl * rights. You may have additional license terms from the party that provided 18118611Snjl * you this software, covering your right to use that party's intellectual 19118611Snjl * property rights. 20118611Snjl * 21118611Snjl * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 22118611Snjl * copy of the source code appearing in this file ("Covered Code") an 23118611Snjl * irrevocable, perpetual, worldwide license under Intel's copyrights in the 24118611Snjl * base code distributed originally by Intel ("Original Intel Code") to copy, 25118611Snjl * make derivatives, distribute, use and display any portion of the Covered 26118611Snjl * Code in any form, with the right to sublicense such rights; and 27118611Snjl * 28118611Snjl * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 29118611Snjl * license (with the right to sublicense), under only those claims of Intel 30118611Snjl * patents that are infringed by the Original Intel Code, to make, use, sell, 31118611Snjl * offer to sell, and import the Covered Code and derivative works thereof 32118611Snjl * solely to the minimum extent necessary to exercise the above copyright 33118611Snjl * license, and in no event shall the patent license extend to any additions 34118611Snjl * to or modifications of the Original Intel Code. No other license or right 35118611Snjl * is granted directly or by implication, estoppel or otherwise; 36118611Snjl * 37118611Snjl * The above copyright and patent license is granted only if the following 38118611Snjl * conditions are met: 39118611Snjl * 40118611Snjl * 3. Conditions 41118611Snjl * 42118611Snjl * 3.1. Redistribution of Source with Rights to Further Distribute Source. 43118611Snjl * Redistribution of source code of any substantial portion of the Covered 44118611Snjl * Code or modification with rights to further distribute source must include 45118611Snjl * the above Copyright Notice, the above License, this list of Conditions, 46118611Snjl * and the following Disclaimer and Export Compliance provision. In addition, 47118611Snjl * Licensee must cause all Covered Code to which Licensee contributes to 48118611Snjl * contain a file documenting the changes Licensee made to create that Covered 49118611Snjl * Code and the date of any change. Licensee must include in that file the 50118611Snjl * documentation of any changes made by any predecessor Licensee. Licensee 51118611Snjl * must include a prominent statement that the modification is derived, 52118611Snjl * directly or indirectly, from Original Intel Code. 53118611Snjl * 54118611Snjl * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 55118611Snjl * Redistribution of source code of any substantial portion of the Covered 56118611Snjl * Code or modification without rights to further distribute source must 57118611Snjl * include the following Disclaimer and Export Compliance provision in the 58118611Snjl * documentation and/or other materials provided with distribution. In 59118611Snjl * addition, Licensee may not authorize further sublicense of source of any 60118611Snjl * portion of the Covered Code, and must include terms to the effect that the 61118611Snjl * license from Licensee to its licensee is limited to the intellectual 62118611Snjl * property embodied in the software Licensee provides to its licensee, and 63118611Snjl * not to intellectual property embodied in modifications its licensee may 64118611Snjl * make. 65118611Snjl * 66118611Snjl * 3.3. Redistribution of Executable. Redistribution in executable form of any 67118611Snjl * substantial portion of the Covered Code or modification must reproduce the 68118611Snjl * above Copyright Notice, and the following Disclaimer and Export Compliance 69118611Snjl * provision in the documentation and/or other materials provided with the 70118611Snjl * distribution. 71118611Snjl * 72118611Snjl * 3.4. Intel retains all right, title, and interest in and to the Original 73118611Snjl * Intel Code. 74118611Snjl * 75118611Snjl * 3.5. Neither the name Intel nor any other trademark owned or controlled by 76118611Snjl * Intel shall be used in advertising or otherwise to promote the sale, use or 77118611Snjl * other dealings in products derived from or relating to the Covered Code 78118611Snjl * without prior written authorization from Intel. 79118611Snjl * 80118611Snjl * 4. Disclaimer and Export Compliance 81118611Snjl * 82118611Snjl * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 83118611Snjl * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 84118611Snjl * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 85118611Snjl * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 86118611Snjl * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 87118611Snjl * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 88118611Snjl * PARTICULAR PURPOSE. 89118611Snjl * 90118611Snjl * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 91118611Snjl * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 92118611Snjl * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 93118611Snjl * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 94118611Snjl * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 95118611Snjl * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 96118611Snjl * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 97118611Snjl * LIMITED REMEDY. 98118611Snjl * 99118611Snjl * 4.3. Licensee shall not export, either directly or indirectly, any of this 100118611Snjl * software or system incorporating such software without first obtaining any 101118611Snjl * required license or other approval from the U. S. Department of Commerce or 102118611Snjl * any other agency or department of the United States Government. In the 103118611Snjl * event Licensee exports any such software from the United States or 104118611Snjl * re-exports any such software from a foreign destination, Licensee shall 105118611Snjl * ensure that the distribution and export/re-export of the software is in 106118611Snjl * compliance with all laws, regulations, orders, or other restrictions of the 107118611Snjl * U.S. Export Administration Regulations. Licensee agrees that neither it nor 108118611Snjl * any of its subsidiaries will export/re-export any technical data, process, 109118611Snjl * software, or service, directly or indirectly, to any country for which the 110118611Snjl * United States government or any agency thereof requires an export license, 111118611Snjl * other governmental approval, or letter of assurance, without first obtaining 112118611Snjl * such license, approval or letter. 113118611Snjl * 114118611Snjl *****************************************************************************/ 115118611Snjl 116118611Snjl#define __ASLLOAD_C__ 117118611Snjl 118151937Sjkim#include <contrib/dev/acpica/compiler/aslcompiler.h> 119193529Sjkim#include <contrib/dev/acpica/include/amlcode.h> 120193529Sjkim#include <contrib/dev/acpica/include/acdispat.h> 121193529Sjkim#include <contrib/dev/acpica/include/acnamesp.h> 122118611Snjl 123118611Snjl#include "aslcompiler.y.h" 124118611Snjl 125118611Snjl#define _COMPONENT ACPI_COMPILER 126118611Snjl ACPI_MODULE_NAME ("aslload") 127118611Snjl 128151937Sjkim/* Local prototypes */ 129118611Snjl 130151937Sjkimstatic ACPI_STATUS 131151937SjkimLdLoadFieldElements ( 132151937Sjkim ACPI_PARSE_OBJECT *Op, 133151937Sjkim ACPI_WALK_STATE *WalkState); 134151937Sjkim 135151937Sjkimstatic ACPI_STATUS 136151937SjkimLdLoadResourceElements ( 137151937Sjkim ACPI_PARSE_OBJECT *Op, 138151937Sjkim ACPI_WALK_STATE *WalkState); 139151937Sjkim 140151937Sjkimstatic ACPI_STATUS 141151937SjkimLdNamespace1Begin ( 142151937Sjkim ACPI_PARSE_OBJECT *Op, 143151937Sjkim UINT32 Level, 144151937Sjkim void *Context); 145151937Sjkim 146151937Sjkimstatic ACPI_STATUS 147193529SjkimLdNamespace2Begin ( 148151937Sjkim ACPI_PARSE_OBJECT *Op, 149151937Sjkim UINT32 Level, 150151937Sjkim void *Context); 151151937Sjkim 152193529Sjkimstatic ACPI_STATUS 153193529SjkimLdCommonNamespaceEnd ( 154193529Sjkim ACPI_PARSE_OBJECT *Op, 155193529Sjkim UINT32 Level, 156193529Sjkim void *Context); 157151937Sjkim 158193529Sjkim 159118611Snjl/******************************************************************************* 160118611Snjl * 161118611Snjl * FUNCTION: LdLoadNamespace 162118611Snjl * 163151937Sjkim * PARAMETERS: RootOp - Root of the parse tree 164118611Snjl * 165118611Snjl * RETURN: Status 166118611Snjl * 167118611Snjl * DESCRIPTION: Perform a walk of the parse tree that in turn loads all of the 168193529Sjkim * named ASL/AML objects into the namespace. The namespace is 169118611Snjl * constructed in order to resolve named references and references 170118611Snjl * to named fields within resource templates/descriptors. 171118611Snjl * 172118611Snjl ******************************************************************************/ 173118611Snjl 174118611SnjlACPI_STATUS 175118611SnjlLdLoadNamespace ( 176118611Snjl ACPI_PARSE_OBJECT *RootOp) 177118611Snjl{ 178118611Snjl ACPI_WALK_STATE *WalkState; 179118611Snjl 180118611Snjl 181118611Snjl DbgPrint (ASL_DEBUG_OUTPUT, "\nCreating namespace\n\n"); 182118611Snjl 183118611Snjl /* Create a new walk state */ 184118611Snjl 185118611Snjl WalkState = AcpiDsCreateWalkState (0, NULL, NULL, NULL); 186118611Snjl if (!WalkState) 187118611Snjl { 188118611Snjl return AE_NO_MEMORY; 189118611Snjl } 190118611Snjl 191193529Sjkim /* Walk the entire parse tree, first pass */ 192118611Snjl 193118611Snjl TrWalkParseTree (RootOp, ASL_WALK_VISIT_TWICE, LdNamespace1Begin, 194193529Sjkim LdCommonNamespaceEnd, WalkState); 195118611Snjl 196193529Sjkim /* Second pass to handle forward references */ 197193529Sjkim 198193529Sjkim TrWalkParseTree (RootOp, ASL_WALK_VISIT_TWICE, LdNamespace2Begin, 199193529Sjkim LdCommonNamespaceEnd, WalkState); 200193529Sjkim 201118611Snjl /* Dump the namespace if debug is enabled */ 202118611Snjl 203118611Snjl AcpiNsDumpTables (ACPI_NS_ALL, ACPI_UINT32_MAX); 204118611Snjl return AE_OK; 205118611Snjl} 206118611Snjl 207118611Snjl 208118611Snjl/******************************************************************************* 209118611Snjl * 210118611Snjl * FUNCTION: LdLoadFieldElements 211118611Snjl * 212151937Sjkim * PARAMETERS: Op - Parent node (Field) 213118611Snjl * WalkState - Current walk state 214118611Snjl * 215118611Snjl * RETURN: Status 216118611Snjl * 217118611Snjl * DESCRIPTION: Enter the named elements of the field (children of the parent) 218118611Snjl * into the namespace. 219118611Snjl * 220118611Snjl ******************************************************************************/ 221118611Snjl 222151937Sjkimstatic ACPI_STATUS 223118611SnjlLdLoadFieldElements ( 224118611Snjl ACPI_PARSE_OBJECT *Op, 225118611Snjl ACPI_WALK_STATE *WalkState) 226118611Snjl{ 227118611Snjl ACPI_PARSE_OBJECT *Child = NULL; 228118611Snjl ACPI_NAMESPACE_NODE *Node; 229118611Snjl ACPI_STATUS Status; 230118611Snjl 231118611Snjl 232118611Snjl /* Get the first named field element */ 233118611Snjl 234118611Snjl switch (Op->Asl.AmlOpcode) 235118611Snjl { 236118611Snjl case AML_BANK_FIELD_OP: 237118611Snjl 238118611Snjl Child = UtGetArg (Op, 6); 239118611Snjl break; 240118611Snjl 241118611Snjl case AML_INDEX_FIELD_OP: 242118611Snjl 243118611Snjl Child = UtGetArg (Op, 5); 244118611Snjl break; 245118611Snjl 246118611Snjl case AML_FIELD_OP: 247118611Snjl 248118611Snjl Child = UtGetArg (Op, 4); 249118611Snjl break; 250118611Snjl 251118611Snjl default: 252118611Snjl /* No other opcodes should arrive here */ 253118611Snjl return (AE_BAD_PARAMETER); 254118611Snjl } 255118611Snjl 256118611Snjl /* Enter all elements into the namespace */ 257118611Snjl 258118611Snjl while (Child) 259118611Snjl { 260118611Snjl switch (Child->Asl.AmlOpcode) 261118611Snjl { 262118611Snjl case AML_INT_RESERVEDFIELD_OP: 263118611Snjl case AML_INT_ACCESSFIELD_OP: 264118611Snjl 265118611Snjl break; 266118611Snjl 267118611Snjl default: 268118611Snjl 269151937Sjkim Status = AcpiNsLookup (WalkState->ScopeInfo, 270151937Sjkim Child->Asl.Value.String, 271151937Sjkim ACPI_TYPE_LOCAL_REGION_FIELD, 272151937Sjkim ACPI_IMODE_LOAD_PASS1, 273151937Sjkim ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE | 274151937Sjkim ACPI_NS_ERROR_IF_FOUND, 275151937Sjkim NULL, &Node); 276118611Snjl if (ACPI_FAILURE (Status)) 277118611Snjl { 278118611Snjl if (Status != AE_ALREADY_EXISTS) 279118611Snjl { 280151937Sjkim AslError (ASL_ERROR, ASL_MSG_CORE_EXCEPTION, Child, 281151937Sjkim Child->Asl.Value.String); 282151937Sjkim return (Status); 283118611Snjl } 284118611Snjl 285118611Snjl /* 286118611Snjl * The name already exists in this scope 287118611Snjl * But continue processing the elements 288118611Snjl */ 289151937Sjkim AslError (ASL_ERROR, ASL_MSG_NAME_EXISTS, Child, 290151937Sjkim Child->Asl.Value.String); 291118611Snjl } 292118611Snjl else 293118611Snjl { 294118611Snjl Child->Asl.Node = Node; 295151937Sjkim Node->Op = Child; 296118611Snjl } 297118611Snjl break; 298118611Snjl } 299118611Snjl Child = Child->Asl.Next; 300118611Snjl } 301118611Snjl return (AE_OK); 302118611Snjl} 303118611Snjl 304118611Snjl 305118611Snjl/******************************************************************************* 306118611Snjl * 307118611Snjl * FUNCTION: LdLoadResourceElements 308118611Snjl * 309151937Sjkim * PARAMETERS: Op - Parent node (Resource Descriptor) 310118611Snjl * WalkState - Current walk state 311118611Snjl * 312118611Snjl * RETURN: Status 313118611Snjl * 314118611Snjl * DESCRIPTION: Enter the named elements of the resource descriptor (children 315118611Snjl * of the parent) into the namespace. 316118611Snjl * 317193529Sjkim * NOTE: In the real AML namespace, these named elements never exist. But 318118611Snjl * we simply use the namespace here as a symbol table so we can look 319118611Snjl * them up as they are referenced. 320118611Snjl * 321118611Snjl ******************************************************************************/ 322118611Snjl 323151937Sjkimstatic ACPI_STATUS 324118611SnjlLdLoadResourceElements ( 325118611Snjl ACPI_PARSE_OBJECT *Op, 326118611Snjl ACPI_WALK_STATE *WalkState) 327118611Snjl{ 328118611Snjl ACPI_PARSE_OBJECT *InitializerOp = NULL; 329118611Snjl ACPI_NAMESPACE_NODE *Node; 330118611Snjl ACPI_STATUS Status; 331118611Snjl 332118611Snjl 333118611Snjl /* 334151937Sjkim * Enter the resource name into the namespace. Name must not already exist. 335151937Sjkim * This opens a scope, so later field names are guaranteed to be new/unique. 336118611Snjl */ 337118611Snjl Status = AcpiNsLookup (WalkState->ScopeInfo, Op->Asl.Namepath, 338151937Sjkim ACPI_TYPE_LOCAL_RESOURCE, ACPI_IMODE_LOAD_PASS1, 339151937Sjkim ACPI_NS_NO_UPSEARCH | ACPI_NS_ERROR_IF_FOUND, 340151937Sjkim WalkState, &Node); 341118611Snjl if (ACPI_FAILURE (Status)) 342118611Snjl { 343151937Sjkim if (Status == AE_ALREADY_EXISTS) 344151937Sjkim { 345151937Sjkim /* Actual node causing the error was saved in ParentMethod */ 346151937Sjkim 347151937Sjkim AslError (ASL_ERROR, ASL_MSG_NAME_EXISTS, 348151937Sjkim (ACPI_PARSE_OBJECT *) Op->Asl.ParentMethod, Op->Asl.Namepath); 349151937Sjkim return (AE_OK); 350151937Sjkim } 351118611Snjl return (Status); 352118611Snjl } 353118611Snjl 354167802Sjkim Node->Value = (UINT32) Op->Asl.Value.Integer; 355167802Sjkim Node->Op = Op; 356167802Sjkim 357118611Snjl /* 358118611Snjl * Now enter the predefined fields, for easy lookup when referenced 359118611Snjl * by the source ASL 360118611Snjl */ 361118611Snjl InitializerOp = ASL_GET_CHILD_NODE (Op); 362118611Snjl while (InitializerOp) 363118611Snjl { 364118611Snjl 365118611Snjl if (InitializerOp->Asl.ExternalName) 366118611Snjl { 367118611Snjl Status = AcpiNsLookup (WalkState->ScopeInfo, 368151937Sjkim InitializerOp->Asl.ExternalName, 369151937Sjkim ACPI_TYPE_LOCAL_RESOURCE_FIELD, 370151937Sjkim ACPI_IMODE_LOAD_PASS1, 371151937Sjkim ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE, 372151937Sjkim NULL, &Node); 373118611Snjl if (ACPI_FAILURE (Status)) 374118611Snjl { 375118611Snjl return (Status); 376118611Snjl } 377118611Snjl 378118611Snjl /* 379118611Snjl * Store the field offset in the namespace node so it 380118611Snjl * can be used when the field is referenced 381118611Snjl */ 382151937Sjkim Node->Value = (UINT32) InitializerOp->Asl.Value.Integer; 383118611Snjl InitializerOp->Asl.Node = Node; 384151937Sjkim Node->Op = InitializerOp; 385118611Snjl 386118611Snjl /* Pass thru the field type (Bitfield or Bytefield) */ 387118611Snjl 388118611Snjl if (InitializerOp->Asl.CompileFlags & NODE_IS_BIT_OFFSET) 389118611Snjl { 390118611Snjl Node->Flags |= ANOBJ_IS_BIT_OFFSET; 391118611Snjl } 392118611Snjl } 393118611Snjl InitializerOp = ASL_GET_PEER_NODE (InitializerOp); 394118611Snjl } 395118611Snjl 396118611Snjl return (AE_OK); 397118611Snjl} 398118611Snjl 399118611Snjl 400118611Snjl/******************************************************************************* 401118611Snjl * 402118611Snjl * FUNCTION: LdNamespace1Begin 403118611Snjl * 404118611Snjl * PARAMETERS: ASL_WALK_CALLBACK 405118611Snjl * 406118611Snjl * RETURN: Status 407118611Snjl * 408193529Sjkim * DESCRIPTION: Descending callback used during the parse tree walk. If this 409118611Snjl * is a named AML opcode, enter into the namespace 410118611Snjl * 411118611Snjl ******************************************************************************/ 412118611Snjl 413151937Sjkimstatic ACPI_STATUS 414118611SnjlLdNamespace1Begin ( 415118611Snjl ACPI_PARSE_OBJECT *Op, 416118611Snjl UINT32 Level, 417118611Snjl void *Context) 418118611Snjl{ 419118611Snjl ACPI_WALK_STATE *WalkState = (ACPI_WALK_STATE *) Context; 420118611Snjl ACPI_NAMESPACE_NODE *Node; 421118611Snjl ACPI_STATUS Status; 422118611Snjl ACPI_OBJECT_TYPE ObjectType; 423118611Snjl ACPI_OBJECT_TYPE ActualObjectType = ACPI_TYPE_ANY; 424118611Snjl char *Path; 425118611Snjl UINT32 Flags = ACPI_NS_NO_UPSEARCH; 426118611Snjl ACPI_PARSE_OBJECT *Arg; 427118611Snjl UINT32 i; 428167802Sjkim BOOLEAN ForceNewScope = FALSE; 429118611Snjl 430118611Snjl 431167802Sjkim ACPI_FUNCTION_NAME (LdNamespace1Begin); 432118611Snjl ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Op %p [%s]\n", 433118611Snjl Op, Op->Asl.ParseOpName)); 434118611Snjl 435118611Snjl 436118611Snjl /* 437118611Snjl * We are only interested in opcodes that have an associated name 438118611Snjl * (or multiple names) 439118611Snjl */ 440118611Snjl switch (Op->Asl.AmlOpcode) 441118611Snjl { 442118611Snjl case AML_BANK_FIELD_OP: 443118611Snjl case AML_INDEX_FIELD_OP: 444118611Snjl case AML_FIELD_OP: 445118611Snjl 446118611Snjl Status = LdLoadFieldElements (Op, WalkState); 447118611Snjl return (Status); 448118611Snjl 449118611Snjl default: 450118611Snjl 451118611Snjl /* All other opcodes go below */ 452118611Snjl break; 453118611Snjl } 454118611Snjl 455118611Snjl /* Check if this object has already been installed in the namespace */ 456118611Snjl 457118611Snjl if (Op->Asl.Node) 458118611Snjl { 459118611Snjl return (AE_OK); 460118611Snjl } 461118611Snjl 462118611Snjl Path = Op->Asl.Namepath; 463118611Snjl if (!Path) 464118611Snjl { 465118611Snjl return (AE_OK); 466118611Snjl } 467118611Snjl 468118611Snjl /* Map the raw opcode into an internal object type */ 469118611Snjl 470118611Snjl switch (Op->Asl.ParseOpcode) 471118611Snjl { 472118611Snjl case PARSEOP_NAME: 473118611Snjl 474151937Sjkim Arg = Op->Asl.Child; /* Get the NameSeg/NameString node */ 475151937Sjkim Arg = Arg->Asl.Next; /* First peer is the object to be associated with the name */ 476118611Snjl 477167802Sjkim /* 478167802Sjkim * If this name refers to a ResourceTemplate, we will need to open 479167802Sjkim * a new scope so that the resource subfield names can be entered into 480167802Sjkim * the namespace underneath this name 481167802Sjkim */ 482167802Sjkim if (Op->Asl.CompileFlags & NODE_IS_RESOURCE_DESC) 483167802Sjkim { 484167802Sjkim ForceNewScope = TRUE; 485167802Sjkim } 486167802Sjkim 487118611Snjl /* Get the data type associated with the named object, not the name itself */ 488118611Snjl 489118611Snjl /* Log2 loop to convert from Btype (binary) to Etype (encoded) */ 490118611Snjl 491118611Snjl ObjectType = 1; 492118611Snjl for (i = 1; i < Arg->Asl.AcpiBtype; i *= 2) 493118611Snjl { 494118611Snjl ObjectType++; 495118611Snjl } 496118611Snjl break; 497118611Snjl 498118611Snjl 499118611Snjl case PARSEOP_EXTERNAL: 500118611Snjl 501118611Snjl /* 502118611Snjl * "External" simply enters a name and type into the namespace. 503118611Snjl * We must be careful to not open a new scope, however, no matter 504118611Snjl * what type the external name refers to (e.g., a method) 505118611Snjl * 506118611Snjl * first child is name, next child is ObjectType 507118611Snjl */ 508118611Snjl ActualObjectType = (UINT8) Op->Asl.Child->Asl.Next->Asl.Value.Integer; 509118611Snjl ObjectType = ACPI_TYPE_ANY; 510167802Sjkim 511167802Sjkim /* 512167802Sjkim * We will mark every new node along the path as "External". This 513167802Sjkim * allows some or all of the nodes to be created later in the ASL 514167802Sjkim * code. Handles cases like this: 515167802Sjkim * 516167802Sjkim * External (\_SB_.PCI0.ABCD, IntObj) 517167802Sjkim * Scope (_SB_) 518167802Sjkim * { 519167802Sjkim * Device (PCI0) 520167802Sjkim * { 521167802Sjkim * } 522167802Sjkim * } 523167802Sjkim * Method (X) 524167802Sjkim * { 525167802Sjkim * Store (\_SB_.PCI0.ABCD, Local0) 526167802Sjkim * } 527167802Sjkim */ 528167802Sjkim Flags |= ACPI_NS_EXTERNAL; 529118611Snjl break; 530118611Snjl 531118611Snjl case PARSEOP_DEFAULT_ARG: 532118611Snjl 533167802Sjkim if (Op->Asl.CompileFlags == NODE_IS_RESOURCE_DESC) 534118611Snjl { 535118611Snjl Status = LdLoadResourceElements (Op, WalkState); 536118611Snjl goto Exit; 537118611Snjl } 538118611Snjl 539118611Snjl ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode); 540118611Snjl break; 541118611Snjl 542118611Snjl 543118611Snjl case PARSEOP_SCOPE: 544118611Snjl 545118611Snjl /* 546118611Snjl * The name referenced by Scope(Name) must already exist at this point. 547118611Snjl * In other words, forward references for Scope() are not supported. 548118611Snjl * The only real reason for this is that the MS interpreter cannot 549193529Sjkim * handle this case. Perhaps someday this case can go away. 550118611Snjl */ 551118611Snjl Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ACPI_TYPE_ANY, 552151937Sjkim ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT, 553151937Sjkim WalkState, &(Node)); 554118611Snjl if (ACPI_FAILURE (Status)) 555118611Snjl { 556118611Snjl if (Status == AE_NOT_FOUND) 557118611Snjl { 558118611Snjl /* The name was not found, go ahead and create it */ 559118611Snjl 560151937Sjkim Status = AcpiNsLookup (WalkState->ScopeInfo, Path, 561151937Sjkim ACPI_TYPE_LOCAL_SCOPE, 562151937Sjkim ACPI_IMODE_LOAD_PASS1, Flags, 563151937Sjkim WalkState, &(Node)); 564118611Snjl 565118611Snjl /* 566118611Snjl * However, this is an error -- primarily because the MS 567118611Snjl * interpreter can't handle a forward reference from the 568118611Snjl * Scope() operator. 569118611Snjl */ 570151937Sjkim AslError (ASL_ERROR, ASL_MSG_NOT_FOUND, Op, 571151937Sjkim Op->Asl.ExternalName); 572151937Sjkim AslError (ASL_ERROR, ASL_MSG_SCOPE_FWD_REF, Op, 573151937Sjkim Op->Asl.ExternalName); 574118611Snjl goto FinishNode; 575118611Snjl } 576118611Snjl 577118611Snjl AslCoreSubsystemError (Op, Status, "Failure from lookup\n", FALSE); 578118611Snjl goto Exit; 579118611Snjl } 580118611Snjl 581118611Snjl /* We found a node with this name, now check the type */ 582118611Snjl 583118611Snjl switch (Node->Type) 584118611Snjl { 585118611Snjl case ACPI_TYPE_LOCAL_SCOPE: 586118611Snjl case ACPI_TYPE_DEVICE: 587118611Snjl case ACPI_TYPE_POWER: 588118611Snjl case ACPI_TYPE_PROCESSOR: 589118611Snjl case ACPI_TYPE_THERMAL: 590118611Snjl 591118611Snjl /* These are acceptable types - they all open a new scope */ 592118611Snjl break; 593118611Snjl 594118611Snjl case ACPI_TYPE_INTEGER: 595118611Snjl case ACPI_TYPE_STRING: 596118611Snjl case ACPI_TYPE_BUFFER: 597118611Snjl 598118611Snjl /* 599151937Sjkim * These types we will allow, but we will change the type. 600151937Sjkim * This enables some existing code of the form: 601118611Snjl * 602118611Snjl * Name (DEB, 0) 603118611Snjl * Scope (DEB) { ... } 604118611Snjl * 605118611Snjl * Which is used to workaround the fact that the MS interpreter 606118611Snjl * does not allow Scope() forward references. 607118611Snjl */ 608128212Snjl sprintf (MsgBuffer, "%s [%s], changing type to [Scope]", 609118611Snjl Op->Asl.ExternalName, AcpiUtGetTypeName (Node->Type)); 610118611Snjl AslError (ASL_REMARK, ASL_MSG_SCOPE_TYPE, Op, MsgBuffer); 611118611Snjl 612151937Sjkim /* Switch the type to scope, open the new scope */ 613151937Sjkim 614128212Snjl Node->Type = ACPI_TYPE_LOCAL_SCOPE; 615151937Sjkim Status = AcpiDsScopeStackPush (Node, ACPI_TYPE_LOCAL_SCOPE, 616151937Sjkim WalkState); 617128212Snjl if (ACPI_FAILURE (Status)) 618128212Snjl { 619128212Snjl return_ACPI_STATUS (Status); 620128212Snjl } 621118611Snjl break; 622118611Snjl 623118611Snjl default: 624118611Snjl 625151937Sjkim /* All other types are an error */ 626151937Sjkim 627151937Sjkim sprintf (MsgBuffer, "%s [%s]", Op->Asl.ExternalName, 628151937Sjkim AcpiUtGetTypeName (Node->Type)); 629118611Snjl AslError (ASL_ERROR, ASL_MSG_SCOPE_TYPE, Op, MsgBuffer); 630118611Snjl 631118611Snjl /* 632118611Snjl * However, switch the type to be an actual scope so 633118611Snjl * that compilation can continue without generating a whole 634193529Sjkim * cascade of additional errors. Open the new scope. 635118611Snjl */ 636128212Snjl Node->Type = ACPI_TYPE_LOCAL_SCOPE; 637151937Sjkim Status = AcpiDsScopeStackPush (Node, ACPI_TYPE_LOCAL_SCOPE, 638151937Sjkim WalkState); 639128212Snjl if (ACPI_FAILURE (Status)) 640128212Snjl { 641128212Snjl return_ACPI_STATUS (Status); 642128212Snjl } 643118611Snjl break; 644118611Snjl } 645118611Snjl 646118611Snjl Status = AE_OK; 647118611Snjl goto FinishNode; 648118611Snjl 649118611Snjl 650118611Snjl default: 651118611Snjl 652118611Snjl ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode); 653118611Snjl break; 654118611Snjl } 655118611Snjl 656118611Snjl 657118611Snjl ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Loading name: %s, (%s)\n", 658118611Snjl Op->Asl.ExternalName, AcpiUtGetTypeName (ObjectType))); 659118611Snjl 660118611Snjl /* The name must not already exist */ 661118611Snjl 662118611Snjl Flags |= ACPI_NS_ERROR_IF_FOUND; 663118611Snjl 664118611Snjl /* 665193529Sjkim * Enter the named type into the internal namespace. We enter the name 666193529Sjkim * as we go downward in the parse tree. Any necessary subobjects that 667151937Sjkim * involve arguments to the opcode must be created as we go back up the 668151937Sjkim * parse tree later. 669118611Snjl */ 670118611Snjl Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ObjectType, 671167802Sjkim ACPI_IMODE_LOAD_PASS1, Flags, WalkState, &Node); 672118611Snjl if (ACPI_FAILURE (Status)) 673118611Snjl { 674118611Snjl if (Status == AE_ALREADY_EXISTS) 675118611Snjl { 676118611Snjl /* The name already exists in this scope */ 677118611Snjl 678118611Snjl if (Node->Type == ACPI_TYPE_LOCAL_SCOPE) 679118611Snjl { 680167802Sjkim /* Allow multiple references to the same scope */ 681167802Sjkim 682118611Snjl Node->Type = (UINT8) ObjectType; 683118611Snjl Status = AE_OK; 684118611Snjl } 685193529Sjkim else if ((Node->Flags & ANOBJ_IS_EXTERNAL) && 686193529Sjkim (Op->Asl.ParseOpcode != PARSEOP_EXTERNAL)) 687167802Sjkim { 688167802Sjkim /* 689167802Sjkim * Allow one create on an object or segment that was 690167802Sjkim * previously declared External 691167802Sjkim */ 692167802Sjkim Node->Flags &= ~ANOBJ_IS_EXTERNAL; 693167802Sjkim Node->Type = (UINT8) ObjectType; 694167802Sjkim 695167802Sjkim /* Just retyped a node, probably will need to open a scope */ 696167802Sjkim 697167802Sjkim if (AcpiNsOpensScope (ObjectType)) 698167802Sjkim { 699167802Sjkim Status = AcpiDsScopeStackPush (Node, ObjectType, WalkState); 700167802Sjkim if (ACPI_FAILURE (Status)) 701167802Sjkim { 702167802Sjkim return_ACPI_STATUS (Status); 703167802Sjkim } 704167802Sjkim } 705167802Sjkim Status = AE_OK; 706167802Sjkim } 707118611Snjl else 708118611Snjl { 709167802Sjkim /* Valid error, object already exists */ 710167802Sjkim 711151937Sjkim AslError (ASL_ERROR, ASL_MSG_NAME_EXISTS, Op, 712151937Sjkim Op->Asl.ExternalName); 713118611Snjl Status = AE_OK; 714118611Snjl goto Exit; 715118611Snjl } 716118611Snjl } 717118611Snjl else 718118611Snjl { 719151937Sjkim AslCoreSubsystemError (Op, Status, 720151937Sjkim "Failure from lookup %s\n", FALSE); 721118611Snjl goto Exit; 722118611Snjl } 723118611Snjl } 724118611Snjl 725167802Sjkim if (ForceNewScope) 726167802Sjkim { 727167802Sjkim Status = AcpiDsScopeStackPush (Node, ObjectType, WalkState); 728167802Sjkim if (ACPI_FAILURE (Status)) 729167802Sjkim { 730167802Sjkim return_ACPI_STATUS (Status); 731167802Sjkim } 732167802Sjkim } 733118611Snjl 734118611SnjlFinishNode: 735118611Snjl /* 736118611Snjl * Point the parse node to the new namespace node, and point 737118611Snjl * the Node back to the original Parse node 738118611Snjl */ 739118611Snjl Op->Asl.Node = Node; 740151937Sjkim Node->Op = Op; 741118611Snjl 742118611Snjl /* Set the actual data type if appropriate (EXTERNAL term only) */ 743118611Snjl 744118611Snjl if (ActualObjectType != ACPI_TYPE_ANY) 745118611Snjl { 746118611Snjl Node->Type = (UINT8) ActualObjectType; 747151937Sjkim Node->Value = ASL_EXTERNAL_METHOD; 748118611Snjl } 749118611Snjl 750118611Snjl if (Op->Asl.ParseOpcode == PARSEOP_METHOD) 751118611Snjl { 752118611Snjl /* 753151937Sjkim * Get the method argument count from "Extra" and save 754151937Sjkim * it in the namespace node 755118611Snjl */ 756151937Sjkim Node->Value = (UINT32) Op->Asl.Extra; 757118611Snjl } 758118611Snjl 759118611SnjlExit: 760118611Snjl return (Status); 761118611Snjl} 762118611Snjl 763118611Snjl 764118611Snjl/******************************************************************************* 765118611Snjl * 766193529Sjkim * FUNCTION: LdNamespace2Begin 767118611Snjl * 768118611Snjl * PARAMETERS: ASL_WALK_CALLBACK 769118611Snjl * 770118611Snjl * RETURN: Status 771118611Snjl * 772193529Sjkim * DESCRIPTION: Descending callback used during the pass 2 parse tree walk. 773193529Sjkim * Second pass resolves some forward references. 774193529Sjkim * 775193529Sjkim * Notes: 776193529Sjkim * Currently only needs to handle the Alias operator. 777193529Sjkim * Could be used to allow forward references from the Scope() operator, but 778193529Sjkim * the MS interpreter does not allow this, so this compiler does not either. 779193529Sjkim * 780193529Sjkim ******************************************************************************/ 781193529Sjkim 782193529Sjkimstatic ACPI_STATUS 783193529SjkimLdNamespace2Begin ( 784193529Sjkim ACPI_PARSE_OBJECT *Op, 785193529Sjkim UINT32 Level, 786193529Sjkim void *Context) 787193529Sjkim{ 788193529Sjkim ACPI_WALK_STATE *WalkState = (ACPI_WALK_STATE *) Context; 789193529Sjkim ACPI_STATUS Status; 790193529Sjkim ACPI_NAMESPACE_NODE *Node; 791193529Sjkim ACPI_OBJECT_TYPE ObjectType; 792193529Sjkim BOOLEAN ForceNewScope = FALSE; 793193529Sjkim ACPI_PARSE_OBJECT *Arg; 794193529Sjkim char *Path; 795193529Sjkim ACPI_NAMESPACE_NODE *TargetNode; 796193529Sjkim 797193529Sjkim 798193529Sjkim ACPI_FUNCTION_NAME (LdNamespace2Begin); 799193529Sjkim ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Op %p [%s]\n", 800193529Sjkim Op, Op->Asl.ParseOpName)); 801193529Sjkim 802193529Sjkim 803193529Sjkim /* Ignore Ops with no namespace node */ 804193529Sjkim 805193529Sjkim Node = Op->Asl.Node; 806193529Sjkim if (!Node) 807193529Sjkim { 808193529Sjkim return (AE_OK); 809193529Sjkim } 810193529Sjkim 811193529Sjkim /* Get the type to determine if we should push the scope */ 812193529Sjkim 813193529Sjkim if ((Op->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG) && 814193529Sjkim (Op->Asl.CompileFlags == NODE_IS_RESOURCE_DESC)) 815193529Sjkim { 816193529Sjkim ObjectType = ACPI_TYPE_LOCAL_RESOURCE; 817193529Sjkim } 818193529Sjkim else 819193529Sjkim { 820193529Sjkim ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode); 821193529Sjkim } 822193529Sjkim 823193529Sjkim /* Push scope for Resource Templates */ 824193529Sjkim 825193529Sjkim if (Op->Asl.ParseOpcode == PARSEOP_NAME) 826193529Sjkim { 827193529Sjkim if (Op->Asl.CompileFlags & NODE_IS_RESOURCE_DESC) 828193529Sjkim { 829193529Sjkim ForceNewScope = TRUE; 830193529Sjkim } 831193529Sjkim } 832193529Sjkim 833193529Sjkim /* Push the scope stack */ 834193529Sjkim 835193529Sjkim if (ForceNewScope || AcpiNsOpensScope (ObjectType)) 836193529Sjkim { 837193529Sjkim Status = AcpiDsScopeStackPush (Node, ObjectType, WalkState); 838193529Sjkim if (ACPI_FAILURE (Status)) 839193529Sjkim { 840193529Sjkim return_ACPI_STATUS (Status); 841193529Sjkim } 842193529Sjkim } 843193529Sjkim 844193529Sjkim if (Op->Asl.ParseOpcode == PARSEOP_ALIAS) 845193529Sjkim { 846193529Sjkim /* Complete the alias node by getting and saving the target node */ 847193529Sjkim 848193529Sjkim /* First child is the alias target */ 849193529Sjkim 850193529Sjkim Arg = Op->Asl.Child; 851193529Sjkim 852193529Sjkim /* Get the target pathname */ 853193529Sjkim 854193529Sjkim Path = Arg->Asl.Namepath; 855193529Sjkim if (!Path) 856193529Sjkim { 857193529Sjkim Status = UtInternalizeName (Arg->Asl.ExternalName, &Path); 858193529Sjkim if (ACPI_FAILURE (Status)) 859193529Sjkim { 860193529Sjkim return (Status); 861193529Sjkim } 862193529Sjkim } 863193529Sjkim 864193529Sjkim /* Get the NS node associated with the target. It must exist. */ 865193529Sjkim 866193529Sjkim Status = AcpiNsLookup (WalkState->ScopeInfo, Path, ACPI_TYPE_ANY, 867193529Sjkim ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE, 868193529Sjkim WalkState, &TargetNode); 869193529Sjkim if (ACPI_FAILURE (Status)) 870193529Sjkim { 871193529Sjkim if (Status == AE_NOT_FOUND) 872193529Sjkim { 873193529Sjkim AslError (ASL_ERROR, ASL_MSG_NOT_FOUND, Op, 874193529Sjkim Op->Asl.ExternalName); 875193529Sjkim 876193529Sjkim /* 877193529Sjkim * The name was not found, go ahead and create it. 878193529Sjkim * This prevents more errors later. 879193529Sjkim */ 880193529Sjkim Status = AcpiNsLookup (WalkState->ScopeInfo, Path, 881193529Sjkim ACPI_TYPE_ANY, 882193529Sjkim ACPI_IMODE_LOAD_PASS1, ACPI_NS_NO_UPSEARCH, 883193529Sjkim WalkState, &(Node)); 884193529Sjkim return (AE_OK); 885193529Sjkim } 886193529Sjkim 887193529Sjkim AslCoreSubsystemError (Op, Status, "Failure from lookup\n", FALSE); 888193529Sjkim return (AE_OK); 889193529Sjkim } 890193529Sjkim 891193529Sjkim /* Save the target node within the alias node */ 892193529Sjkim 893193529Sjkim Node->Object = ACPI_CAST_PTR (ACPI_OPERAND_OBJECT, TargetNode); 894193529Sjkim } 895193529Sjkim 896193529Sjkim return (AE_OK); 897193529Sjkim} 898193529Sjkim 899193529Sjkim 900193529Sjkim/******************************************************************************* 901193529Sjkim * 902193529Sjkim * FUNCTION: LdCommonNamespaceEnd 903193529Sjkim * 904193529Sjkim * PARAMETERS: ASL_WALK_CALLBACK 905193529Sjkim * 906193529Sjkim * RETURN: Status 907193529Sjkim * 908118611Snjl * DESCRIPTION: Ascending callback used during the loading of the namespace, 909118611Snjl * We only need to worry about managing the scope stack here. 910118611Snjl * 911118611Snjl ******************************************************************************/ 912118611Snjl 913151937Sjkimstatic ACPI_STATUS 914193529SjkimLdCommonNamespaceEnd ( 915118611Snjl ACPI_PARSE_OBJECT *Op, 916118611Snjl UINT32 Level, 917118611Snjl void *Context) 918118611Snjl{ 919118611Snjl ACPI_WALK_STATE *WalkState = (ACPI_WALK_STATE *) Context; 920118611Snjl ACPI_OBJECT_TYPE ObjectType; 921167802Sjkim BOOLEAN ForceNewScope = FALSE; 922118611Snjl 923118611Snjl 924193529Sjkim ACPI_FUNCTION_NAME (LdCommonNamespaceEnd); 925118611Snjl 926118611Snjl 927118611Snjl /* We are only interested in opcodes that have an associated name */ 928118611Snjl 929118611Snjl if (!Op->Asl.Namepath) 930118611Snjl { 931118611Snjl return (AE_OK); 932118611Snjl } 933118611Snjl 934118611Snjl /* Get the type to determine if we should pop the scope */ 935118611Snjl 936118611Snjl if ((Op->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG) && 937118611Snjl (Op->Asl.CompileFlags == NODE_IS_RESOURCE_DESC)) 938118611Snjl { 939118611Snjl /* TBD: Merge into AcpiDsMapNamedOpcodeToDataType */ 940118611Snjl 941118611Snjl ObjectType = ACPI_TYPE_LOCAL_RESOURCE; 942118611Snjl } 943118611Snjl else 944118611Snjl { 945118611Snjl ObjectType = AslMapNamedOpcodeToDataType (Op->Asl.AmlOpcode); 946118611Snjl } 947118611Snjl 948167802Sjkim /* Pop scope that was pushed for Resource Templates */ 949167802Sjkim 950167802Sjkim if (Op->Asl.ParseOpcode == PARSEOP_NAME) 951167802Sjkim { 952167802Sjkim if (Op->Asl.CompileFlags & NODE_IS_RESOURCE_DESC) 953167802Sjkim { 954167802Sjkim ForceNewScope = TRUE; 955167802Sjkim } 956167802Sjkim } 957167802Sjkim 958118611Snjl /* Pop the scope stack */ 959118611Snjl 960167802Sjkim if (ForceNewScope || AcpiNsOpensScope (ObjectType)) 961118611Snjl { 962118611Snjl ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, 963118611Snjl "(%s): Popping scope for Op [%s] %p\n", 964118611Snjl AcpiUtGetTypeName (ObjectType), Op->Asl.ParseOpName, Op)); 965118611Snjl 966151937Sjkim (void) AcpiDsScopeStackPop (WalkState); 967118611Snjl } 968118611Snjl 969118611Snjl return (AE_OK); 970118611Snjl} 971118611Snjl 972118611Snjl 973