asltree.c revision 167802
1118611Snjl 2118611Snjl/****************************************************************************** 3118611Snjl * 4118611Snjl * Module Name: asltree - parse tree management 5167802Sjkim * $Revision: 1.63 $ 6118611Snjl * 7118611Snjl *****************************************************************************/ 8118611Snjl 9118611Snjl/****************************************************************************** 10118611Snjl * 11118611Snjl * 1. Copyright Notice 12118611Snjl * 13167802Sjkim * Some or all of this work - Copyright (c) 1999 - 2007, Intel Corp. 14118611Snjl * All rights reserved. 15118611Snjl * 16118611Snjl * 2. License 17118611Snjl * 18118611Snjl * 2.1. This is your license from Intel Corp. under its intellectual property 19118611Snjl * rights. You may have additional license terms from the party that provided 20118611Snjl * you this software, covering your right to use that party's intellectual 21118611Snjl * property rights. 22118611Snjl * 23118611Snjl * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 24118611Snjl * copy of the source code appearing in this file ("Covered Code") an 25118611Snjl * irrevocable, perpetual, worldwide license under Intel's copyrights in the 26118611Snjl * base code distributed originally by Intel ("Original Intel Code") to copy, 27118611Snjl * make derivatives, distribute, use and display any portion of the Covered 28118611Snjl * Code in any form, with the right to sublicense such rights; and 29118611Snjl * 30118611Snjl * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 31118611Snjl * license (with the right to sublicense), under only those claims of Intel 32118611Snjl * patents that are infringed by the Original Intel Code, to make, use, sell, 33118611Snjl * offer to sell, and import the Covered Code and derivative works thereof 34118611Snjl * solely to the minimum extent necessary to exercise the above copyright 35118611Snjl * license, and in no event shall the patent license extend to any additions 36118611Snjl * to or modifications of the Original Intel Code. No other license or right 37118611Snjl * is granted directly or by implication, estoppel or otherwise; 38118611Snjl * 39118611Snjl * The above copyright and patent license is granted only if the following 40118611Snjl * conditions are met: 41118611Snjl * 42118611Snjl * 3. Conditions 43118611Snjl * 44118611Snjl * 3.1. Redistribution of Source with Rights to Further Distribute Source. 45118611Snjl * Redistribution of source code of any substantial portion of the Covered 46118611Snjl * Code or modification with rights to further distribute source must include 47118611Snjl * the above Copyright Notice, the above License, this list of Conditions, 48118611Snjl * and the following Disclaimer and Export Compliance provision. In addition, 49118611Snjl * Licensee must cause all Covered Code to which Licensee contributes to 50118611Snjl * contain a file documenting the changes Licensee made to create that Covered 51118611Snjl * Code and the date of any change. Licensee must include in that file the 52118611Snjl * documentation of any changes made by any predecessor Licensee. Licensee 53118611Snjl * must include a prominent statement that the modification is derived, 54118611Snjl * directly or indirectly, from Original Intel Code. 55118611Snjl * 56118611Snjl * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 57118611Snjl * Redistribution of source code of any substantial portion of the Covered 58118611Snjl * Code or modification without rights to further distribute source must 59118611Snjl * include the following Disclaimer and Export Compliance provision in the 60118611Snjl * documentation and/or other materials provided with distribution. In 61118611Snjl * addition, Licensee may not authorize further sublicense of source of any 62118611Snjl * portion of the Covered Code, and must include terms to the effect that the 63118611Snjl * license from Licensee to its licensee is limited to the intellectual 64118611Snjl * property embodied in the software Licensee provides to its licensee, and 65118611Snjl * not to intellectual property embodied in modifications its licensee may 66118611Snjl * make. 67118611Snjl * 68118611Snjl * 3.3. Redistribution of Executable. Redistribution in executable form of any 69118611Snjl * substantial portion of the Covered Code or modification must reproduce the 70118611Snjl * above Copyright Notice, and the following Disclaimer and Export Compliance 71118611Snjl * provision in the documentation and/or other materials provided with the 72118611Snjl * distribution. 73118611Snjl * 74118611Snjl * 3.4. Intel retains all right, title, and interest in and to the Original 75118611Snjl * Intel Code. 76118611Snjl * 77118611Snjl * 3.5. Neither the name Intel nor any other trademark owned or controlled by 78118611Snjl * Intel shall be used in advertising or otherwise to promote the sale, use or 79118611Snjl * other dealings in products derived from or relating to the Covered Code 80118611Snjl * without prior written authorization from Intel. 81118611Snjl * 82118611Snjl * 4. Disclaimer and Export Compliance 83118611Snjl * 84118611Snjl * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 85118611Snjl * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 86118611Snjl * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 87118611Snjl * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 88118611Snjl * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 89118611Snjl * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 90118611Snjl * PARTICULAR PURPOSE. 91118611Snjl * 92118611Snjl * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 93118611Snjl * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 94118611Snjl * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 95118611Snjl * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 96118611Snjl * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 97118611Snjl * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 98118611Snjl * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 99118611Snjl * LIMITED REMEDY. 100118611Snjl * 101118611Snjl * 4.3. Licensee shall not export, either directly or indirectly, any of this 102118611Snjl * software or system incorporating such software without first obtaining any 103118611Snjl * required license or other approval from the U. S. Department of Commerce or 104118611Snjl * any other agency or department of the United States Government. In the 105118611Snjl * event Licensee exports any such software from the United States or 106118611Snjl * re-exports any such software from a foreign destination, Licensee shall 107118611Snjl * ensure that the distribution and export/re-export of the software is in 108118611Snjl * compliance with all laws, regulations, orders, or other restrictions of the 109118611Snjl * U.S. Export Administration Regulations. Licensee agrees that neither it nor 110118611Snjl * any of its subsidiaries will export/re-export any technical data, process, 111118611Snjl * software, or service, directly or indirectly, to any country for which the 112118611Snjl * United States government or any agency thereof requires an export license, 113118611Snjl * other governmental approval, or letter of assurance, without first obtaining 114118611Snjl * such license, approval or letter. 115118611Snjl * 116118611Snjl *****************************************************************************/ 117118611Snjl 118118611Snjl 119151937Sjkim#include <contrib/dev/acpica/compiler/aslcompiler.h> 120118611Snjl#include "aslcompiler.y.h" 121118611Snjl 122118611Snjl#define _COMPONENT ACPI_COMPILER 123118611Snjl ACPI_MODULE_NAME ("asltree") 124118611Snjl 125151937Sjkim/* Local prototypes */ 126118611Snjl 127151937Sjkimstatic ACPI_PARSE_OBJECT * 128151937SjkimTrGetNextNode ( 129151937Sjkim void); 130151937Sjkim 131151937Sjkimstatic char * 132151937SjkimTrGetNodeFlagName ( 133151937Sjkim UINT32 Flags); 134151937Sjkim 135151937Sjkim 136118611Snjl/******************************************************************************* 137118611Snjl * 138118611Snjl * FUNCTION: TrGetNextNode 139118611Snjl * 140118611Snjl * PARAMETERS: None 141118611Snjl * 142118611Snjl * RETURN: New parse node. Aborts on allocation failure 143118611Snjl * 144118611Snjl * DESCRIPTION: Allocate a new parse node for the parse tree. Bypass the local 145118611Snjl * dynamic memory manager for performance reasons (This has a 146118611Snjl * major impact on the speed of the compiler.) 147118611Snjl * 148118611Snjl ******************************************************************************/ 149118611Snjl 150151937Sjkimstatic ACPI_PARSE_OBJECT * 151151937SjkimTrGetNextNode ( 152151937Sjkim void) 153118611Snjl{ 154118611Snjl 155118611Snjl if (Gbl_NodeCacheNext >= Gbl_NodeCacheLast) 156118611Snjl { 157151937Sjkim Gbl_NodeCacheNext = UtLocalCalloc (sizeof (ACPI_PARSE_OBJECT) * 158151937Sjkim ASL_NODE_CACHE_SIZE); 159118611Snjl Gbl_NodeCacheLast = Gbl_NodeCacheNext + ASL_NODE_CACHE_SIZE; 160118611Snjl } 161118611Snjl 162118611Snjl return (Gbl_NodeCacheNext++); 163118611Snjl} 164118611Snjl 165118611Snjl 166118611Snjl/******************************************************************************* 167118611Snjl * 168118611Snjl * FUNCTION: TrAllocateNode 169118611Snjl * 170118611Snjl * PARAMETERS: ParseOpcode - Opcode to be assigned to the node 171118611Snjl * 172118611Snjl * RETURN: New parse node. Aborts on allocation failure 173118611Snjl * 174118611Snjl * DESCRIPTION: Allocate and initialize a new parse node for the parse tree 175118611Snjl * 176118611Snjl ******************************************************************************/ 177118611Snjl 178118611SnjlACPI_PARSE_OBJECT * 179118611SnjlTrAllocateNode ( 180118611Snjl UINT32 ParseOpcode) 181118611Snjl{ 182118611Snjl ACPI_PARSE_OBJECT *Op; 183118611Snjl 184118611Snjl 185118611Snjl Op = TrGetNextNode (); 186118611Snjl 187118611Snjl Op->Asl.ParseOpcode = (UINT16) ParseOpcode; 188118611Snjl Op->Asl.Filename = Gbl_Files[ASL_FILE_INPUT].Filename; 189118611Snjl Op->Asl.LineNumber = Gbl_CurrentLineNumber; 190118611Snjl Op->Asl.LogicalLineNumber = Gbl_LogicalLineNumber; 191118611Snjl Op->Asl.LogicalByteOffset = Gbl_CurrentLineOffset; 192118611Snjl Op->Asl.Column = Gbl_CurrentColumn; 193118611Snjl 194118611Snjl UtSetParseOpName (Op); 195118611Snjl return Op; 196118611Snjl} 197118611Snjl 198118611Snjl 199118611Snjl/******************************************************************************* 200118611Snjl * 201118611Snjl * FUNCTION: TrReleaseNode 202118611Snjl * 203118611Snjl * PARAMETERS: Op - Op to be released 204118611Snjl * 205118611Snjl * RETURN: None 206118611Snjl * 207118611Snjl * DESCRIPTION: "release" a node. In truth, nothing is done since the node 208118611Snjl * is part of a larger buffer 209118611Snjl * 210118611Snjl ******************************************************************************/ 211118611Snjl 212118611Snjlvoid 213118611SnjlTrReleaseNode ( 214118611Snjl ACPI_PARSE_OBJECT *Op) 215118611Snjl{ 216118611Snjl 217118611Snjl return; 218118611Snjl} 219118611Snjl 220118611Snjl 221118611Snjl/******************************************************************************* 222118611Snjl * 223118611Snjl * FUNCTION: TrUpdateNode 224118611Snjl * 225118611Snjl * PARAMETERS: ParseOpcode - New opcode to be assigned to the node 226118611Snjl * Op - An existing parse node 227118611Snjl * 228118611Snjl * RETURN: The updated node 229118611Snjl * 230118611Snjl * DESCRIPTION: Change the parse opcode assigned to a node. Usually used to 231118611Snjl * change an opcode to DEFAULT_ARG so that the node is ignored 232118611Snjl * during the code generation. Also used to set generic integers 233118611Snjl * to a specific size (8, 16, 32, or 64 bits) 234118611Snjl * 235118611Snjl ******************************************************************************/ 236118611Snjl 237118611SnjlACPI_PARSE_OBJECT * 238118611SnjlTrUpdateNode ( 239118611Snjl UINT32 ParseOpcode, 240118611Snjl ACPI_PARSE_OBJECT *Op) 241118611Snjl{ 242118611Snjl 243118611Snjl if (!Op) 244118611Snjl { 245118611Snjl return NULL; 246118611Snjl } 247118611Snjl 248118611Snjl DbgPrint (ASL_PARSE_OUTPUT, 249118611Snjl "\nUpdateNode: Old - %s, New - %s\n\n", 250118611Snjl UtGetOpName (Op->Asl.ParseOpcode), 251118611Snjl UtGetOpName (ParseOpcode)); 252118611Snjl 253118611Snjl /* Assign new opcode and name */ 254118611Snjl 255118611Snjl if (Op->Asl.ParseOpcode == PARSEOP_ONES) 256118611Snjl { 257118611Snjl switch (ParseOpcode) 258118611Snjl { 259118611Snjl case PARSEOP_BYTECONST: 260118611Snjl Op->Asl.Value.Integer = 0xFF; 261118611Snjl break; 262118611Snjl 263118611Snjl case PARSEOP_WORDCONST: 264118611Snjl Op->Asl.Value.Integer = 0xFFFF; 265118611Snjl break; 266118611Snjl 267118611Snjl case PARSEOP_DWORDCONST: 268118611Snjl Op->Asl.Value.Integer = 0xFFFFFFFF; 269118611Snjl break; 270118611Snjl 271118611Snjl default: 272118611Snjl /* Don't care about others, don't need to check QWORD */ 273118611Snjl break; 274118611Snjl } 275118611Snjl } 276118611Snjl 277118611Snjl Op->Asl.ParseOpcode = (UINT16) ParseOpcode; 278118611Snjl UtSetParseOpName (Op); 279118611Snjl 280118611Snjl /* 281118611Snjl * For the BYTE, WORD, and DWORD constants, make sure that the integer 282118611Snjl * that was passed in will actually fit into the data type 283118611Snjl */ 284118611Snjl switch (ParseOpcode) 285118611Snjl { 286118611Snjl case PARSEOP_BYTECONST: 287118611Snjl Op = UtCheckIntegerRange (Op, 0x00, ACPI_UINT8_MAX); 288118611Snjl break; 289118611Snjl 290118611Snjl case PARSEOP_WORDCONST: 291118611Snjl Op = UtCheckIntegerRange (Op, 0x00, ACPI_UINT16_MAX); 292118611Snjl break; 293118611Snjl 294118611Snjl case PARSEOP_DWORDCONST: 295118611Snjl Op = UtCheckIntegerRange (Op, 0x00, ACPI_UINT32_MAX); 296118611Snjl break; 297118611Snjl 298118611Snjl default: 299118611Snjl /* Don't care about others, don't need to check QWORD */ 300118611Snjl break; 301118611Snjl } 302118611Snjl 303118611Snjl return Op; 304118611Snjl} 305118611Snjl 306118611Snjl 307118611Snjl/******************************************************************************* 308118611Snjl * 309118611Snjl * FUNCTION: TrGetNodeFlagName 310118611Snjl * 311118611Snjl * PARAMETERS: Flags - Flags word to be decoded 312118611Snjl * 313151937Sjkim * RETURN: Name string. Always returns a valid string pointer. 314118611Snjl * 315118611Snjl * DESCRIPTION: Decode a flags word 316118611Snjl * 317118611Snjl ******************************************************************************/ 318118611Snjl 319151937Sjkimstatic char * 320118611SnjlTrGetNodeFlagName ( 321118611Snjl UINT32 Flags) 322118611Snjl{ 323118611Snjl 324118611Snjl switch (Flags) 325118611Snjl { 326118611Snjl case NODE_VISITED: 327118611Snjl return ("NODE_VISITED"); 328118611Snjl 329118611Snjl case NODE_AML_PACKAGE: 330118611Snjl return ("NODE_AML_PACKAGE"); 331118611Snjl 332118611Snjl case NODE_IS_TARGET: 333118611Snjl return ("NODE_IS_TARGET"); 334118611Snjl 335118611Snjl case NODE_IS_RESOURCE_DESC: 336118611Snjl return ("NODE_IS_RESOURCE_DESC"); 337118611Snjl 338118611Snjl case NODE_IS_RESOURCE_FIELD: 339118611Snjl return ("NODE_IS_RESOURCE_FIELD"); 340118611Snjl 341118611Snjl case NODE_HAS_NO_EXIT: 342118611Snjl return ("NODE_HAS_NO_EXIT"); 343118611Snjl 344118611Snjl case NODE_IF_HAS_NO_EXIT: 345118611Snjl return ("NODE_IF_HAS_NO_EXIT"); 346118611Snjl 347118611Snjl case NODE_NAME_INTERNALIZED: 348118611Snjl return ("NODE_NAME_INTERNALIZED"); 349118611Snjl 350118611Snjl case NODE_METHOD_NO_RETVAL: 351118611Snjl return ("NODE_METHOD_NO_RETVAL"); 352118611Snjl 353118611Snjl case NODE_METHOD_SOME_NO_RETVAL: 354118611Snjl return ("NODE_METHOD_SOME_NO_RETVAL"); 355118611Snjl 356118611Snjl case NODE_RESULT_NOT_USED: 357118611Snjl return ("NODE_RESULT_NOT_USED"); 358118611Snjl 359118611Snjl case NODE_METHOD_TYPED: 360118611Snjl return ("NODE_METHOD_TYPED"); 361118611Snjl 362118611Snjl case NODE_IS_BIT_OFFSET: 363118611Snjl return ("NODE_IS_BIT_OFFSET"); 364118611Snjl 365118611Snjl case NODE_COMPILE_TIME_CONST: 366118611Snjl return ("NODE_COMPILE_TIME_CONST"); 367118611Snjl 368118611Snjl case NODE_IS_TERM_ARG: 369118611Snjl return ("NODE_IS_TERM_ARG"); 370118611Snjl 371118611Snjl case NODE_WAS_ONES_OP: 372118611Snjl return ("NODE_WAS_ONES_OP"); 373118611Snjl 374118611Snjl case NODE_IS_NAME_DECLARATION: 375118611Snjl return ("NODE_IS_NAME_DECLARATION"); 376118611Snjl 377118611Snjl default: 378118611Snjl return ("Multiple Flags (or unknown flag) set"); 379118611Snjl } 380118611Snjl} 381118611Snjl 382118611Snjl 383118611Snjl/******************************************************************************* 384118611Snjl * 385118611Snjl * FUNCTION: TrSetNodeFlags 386118611Snjl * 387151937Sjkim * PARAMETERS: Op - An existing parse node 388118611Snjl * Flags - New flags word 389118611Snjl * 390151937Sjkim * RETURN: The updated parser op 391118611Snjl * 392118611Snjl * DESCRIPTION: Set bits in the node flags word. Will not clear bits, only set 393118611Snjl * 394118611Snjl ******************************************************************************/ 395118611Snjl 396118611SnjlACPI_PARSE_OBJECT * 397118611SnjlTrSetNodeFlags ( 398118611Snjl ACPI_PARSE_OBJECT *Op, 399118611Snjl UINT32 Flags) 400118611Snjl{ 401118611Snjl 402118611Snjl DbgPrint (ASL_PARSE_OUTPUT, 403151937Sjkim "\nSetNodeFlags: Op %p, %8.8X %s\n\n", Op, Flags, 404151937Sjkim TrGetNodeFlagName (Flags)); 405118611Snjl 406118611Snjl if (!Op) 407118611Snjl { 408118611Snjl return NULL; 409118611Snjl } 410118611Snjl 411118611Snjl Op->Asl.CompileFlags |= Flags; 412118611Snjl 413118611Snjl return Op; 414118611Snjl} 415118611Snjl 416118611Snjl 417118611Snjl/******************************************************************************* 418118611Snjl * 419118611Snjl * FUNCTION: TrSetEndLineNumber 420118611Snjl * 421118611Snjl * PARAMETERS: Op - An existing parse node 422118611Snjl * 423118611Snjl * RETURN: None. 424118611Snjl * 425118611Snjl * DESCRIPTION: Set the ending line numbers (file line and logical line) of a 426118611Snjl * parse node to the current line numbers. 427118611Snjl * 428118611Snjl ******************************************************************************/ 429118611Snjl 430118611Snjlvoid 431118611SnjlTrSetEndLineNumber ( 432118611Snjl ACPI_PARSE_OBJECT *Op) 433118611Snjl{ 434118611Snjl 435118611Snjl /* If the end line # is already set, just return */ 436118611Snjl 437118611Snjl if (Op->Asl.EndLine) 438118611Snjl { 439118611Snjl return; 440118611Snjl } 441118611Snjl 442118611Snjl Op->Asl.EndLine = Gbl_CurrentLineNumber; 443118611Snjl Op->Asl.EndLogicalLine = Gbl_LogicalLineNumber; 444118611Snjl} 445118611Snjl 446118611Snjl 447118611Snjl/******************************************************************************* 448118611Snjl * 449118611Snjl * FUNCTION: TrCreateLeafNode 450118611Snjl * 451118611Snjl * PARAMETERS: ParseOpcode - New opcode to be assigned to the node 452118611Snjl * 453118611Snjl * RETURN: Pointer to the new node. Aborts on allocation failure 454118611Snjl * 455118611Snjl * DESCRIPTION: Create a simple leaf node (no children or peers, and no value 456118611Snjl * assigned to the node) 457118611Snjl * 458118611Snjl ******************************************************************************/ 459118611Snjl 460118611SnjlACPI_PARSE_OBJECT * 461118611SnjlTrCreateLeafNode ( 462118611Snjl UINT32 ParseOpcode) 463118611Snjl{ 464118611Snjl ACPI_PARSE_OBJECT *Op; 465118611Snjl 466118611Snjl 467118611Snjl Op = TrAllocateNode (ParseOpcode); 468118611Snjl 469118611Snjl DbgPrint (ASL_PARSE_OUTPUT, 470167802Sjkim "\nCreateLeafNode Ln/Col %d/%d NewNode %p Op %s\n\n", 471167802Sjkim Op->Asl.LineNumber, Op->Asl.Column, Op, UtGetOpName(ParseOpcode)); 472118611Snjl 473118611Snjl return Op; 474118611Snjl} 475118611Snjl 476118611Snjl 477118611Snjl/******************************************************************************* 478118611Snjl * 479118611Snjl * FUNCTION: TrCreateValuedLeafNode 480118611Snjl * 481118611Snjl * PARAMETERS: ParseOpcode - New opcode to be assigned to the node 482118611Snjl * Value - Value to be assigned to the node 483118611Snjl * 484118611Snjl * RETURN: Pointer to the new node. Aborts on allocation failure 485118611Snjl * 486118611Snjl * DESCRIPTION: Create a leaf node (no children or peers) with a value 487118611Snjl * assigned to it 488118611Snjl * 489118611Snjl ******************************************************************************/ 490118611Snjl 491118611SnjlACPI_PARSE_OBJECT * 492118611SnjlTrCreateValuedLeafNode ( 493118611Snjl UINT32 ParseOpcode, 494118611Snjl ACPI_INTEGER Value) 495118611Snjl{ 496118611Snjl ACPI_PARSE_OBJECT *Op; 497118611Snjl 498118611Snjl 499118611Snjl Op = TrAllocateNode (ParseOpcode); 500118611Snjl 501118611Snjl DbgPrint (ASL_PARSE_OUTPUT, 502167802Sjkim "\nCreateValuedLeafNode Ln/Col %d/%d NewNode %p Op %s Value %8.8X%8.8X ", 503167802Sjkim Op->Asl.LineNumber, Op->Asl.Column, Op, UtGetOpName(ParseOpcode), 504123315Snjl ACPI_FORMAT_UINT64 (Value)); 505118611Snjl Op->Asl.Value.Integer = Value; 506118611Snjl 507118611Snjl switch (ParseOpcode) 508118611Snjl { 509118611Snjl case PARSEOP_STRING_LITERAL: 510118611Snjl DbgPrint (ASL_PARSE_OUTPUT, "STRING->%s", Value); 511118611Snjl break; 512118611Snjl 513118611Snjl case PARSEOP_NAMESEG: 514118611Snjl DbgPrint (ASL_PARSE_OUTPUT, "NAMESEG->%s", Value); 515118611Snjl break; 516118611Snjl 517118611Snjl case PARSEOP_NAMESTRING: 518118611Snjl DbgPrint (ASL_PARSE_OUTPUT, "NAMESTRING->%s", Value); 519118611Snjl break; 520118611Snjl 521118611Snjl case PARSEOP_EISAID: 522118611Snjl DbgPrint (ASL_PARSE_OUTPUT, "EISAID->%s", Value); 523118611Snjl break; 524118611Snjl 525118611Snjl case PARSEOP_METHOD: 526118611Snjl DbgPrint (ASL_PARSE_OUTPUT, "METHOD"); 527118611Snjl break; 528118611Snjl 529118611Snjl case PARSEOP_INTEGER: 530118611Snjl DbgPrint (ASL_PARSE_OUTPUT, "INTEGER"); 531118611Snjl break; 532118611Snjl 533118611Snjl default: 534118611Snjl break; 535118611Snjl } 536118611Snjl 537118611Snjl DbgPrint (ASL_PARSE_OUTPUT, "\n\n"); 538118611Snjl return Op; 539118611Snjl} 540118611Snjl 541118611Snjl 542118611Snjl/******************************************************************************* 543118611Snjl * 544118611Snjl * FUNCTION: TrCreateNode 545118611Snjl * 546118611Snjl * PARAMETERS: ParseOpcode - Opcode to be assigned to the node 547118611Snjl * NumChildren - Number of children to follow 548118611Snjl * ... - A list of child nodes to link to the new 549118611Snjl * node. NumChildren long. 550118611Snjl * 551118611Snjl * RETURN: Pointer to the new node. Aborts on allocation failure 552118611Snjl * 553118611Snjl * DESCRIPTION: Create a new parse node and link together a list of child 554118611Snjl * nodes underneath the new node. 555118611Snjl * 556118611Snjl ******************************************************************************/ 557118611Snjl 558118611SnjlACPI_PARSE_OBJECT * 559118611SnjlTrCreateNode ( 560118611Snjl UINT32 ParseOpcode, 561118611Snjl UINT32 NumChildren, 562118611Snjl ...) 563118611Snjl{ 564118611Snjl ACPI_PARSE_OBJECT *Op; 565118611Snjl ACPI_PARSE_OBJECT *Child; 566118611Snjl ACPI_PARSE_OBJECT *PrevChild; 567118611Snjl va_list ap; 568118611Snjl UINT32 i; 569118611Snjl BOOLEAN FirstChild; 570118611Snjl 571118611Snjl 572118611Snjl va_start (ap, NumChildren); 573118611Snjl 574118611Snjl /* Allocate one new node */ 575118611Snjl 576118611Snjl Op = TrAllocateNode (ParseOpcode); 577118611Snjl 578118611Snjl DbgPrint (ASL_PARSE_OUTPUT, 579167802Sjkim "\nCreateNode Ln/Col %d/%d NewParent %p Child %d Op %s ", 580167802Sjkim Op->Asl.LineNumber, Op->Asl.Column, Op, NumChildren, UtGetOpName(ParseOpcode)); 581118611Snjl 582118611Snjl /* Some extra debug output based on the parse opcode */ 583118611Snjl 584118611Snjl switch (ParseOpcode) 585118611Snjl { 586118611Snjl case PARSEOP_DEFINITIONBLOCK: 587118611Snjl RootNode = Op; 588118611Snjl DbgPrint (ASL_PARSE_OUTPUT, "DEFINITION_BLOCK (Tree Completed)->"); 589118611Snjl break; 590118611Snjl 591118611Snjl case PARSEOP_OPERATIONREGION: 592118611Snjl DbgPrint (ASL_PARSE_OUTPUT, "OPREGION->"); 593118611Snjl break; 594118611Snjl 595118611Snjl case PARSEOP_OR: 596118611Snjl DbgPrint (ASL_PARSE_OUTPUT, "OR->"); 597118611Snjl break; 598118611Snjl 599118611Snjl default: 600118611Snjl /* Nothing to do for other opcodes */ 601118611Snjl break; 602118611Snjl } 603118611Snjl 604118611Snjl /* Link the new node to its children */ 605118611Snjl 606118611Snjl PrevChild = NULL; 607118611Snjl FirstChild = TRUE; 608118611Snjl for (i = 0; i < NumChildren; i++) 609118611Snjl { 610118611Snjl /* Get the next child */ 611118611Snjl 612118611Snjl Child = va_arg (ap, ACPI_PARSE_OBJECT *); 613118611Snjl DbgPrint (ASL_PARSE_OUTPUT, "%p, ", Child); 614118611Snjl 615118611Snjl /* 616118611Snjl * If child is NULL, this means that an optional argument 617118611Snjl * was omitted. We must create a placeholder with a special 618118611Snjl * opcode (DEFAULT_ARG) so that the code generator will know 619118611Snjl * that it must emit the correct default for this argument 620118611Snjl */ 621118611Snjl if (!Child) 622118611Snjl { 623118611Snjl Child = TrAllocateNode (PARSEOP_DEFAULT_ARG); 624118611Snjl } 625118611Snjl 626118611Snjl /* Link first child to parent */ 627118611Snjl 628118611Snjl if (FirstChild) 629118611Snjl { 630118611Snjl FirstChild = FALSE; 631118611Snjl Op->Asl.Child = Child; 632118611Snjl } 633118611Snjl 634118611Snjl /* Point all children to parent */ 635118611Snjl 636118611Snjl Child->Asl.Parent = Op; 637118611Snjl 638118611Snjl /* Link children in a peer list */ 639118611Snjl 640118611Snjl if (PrevChild) 641118611Snjl { 642118611Snjl PrevChild->Asl.Next = Child; 643118611Snjl }; 644118611Snjl 645118611Snjl /* 646118611Snjl * This child might be a list, point all nodes in the list 647118611Snjl * to the same parent 648118611Snjl */ 649118611Snjl while (Child->Asl.Next) 650118611Snjl { 651118611Snjl Child = Child->Asl.Next; 652118611Snjl Child->Asl.Parent = Op; 653118611Snjl } 654118611Snjl 655118611Snjl PrevChild = Child; 656118611Snjl } 657118611Snjl va_end(ap); 658118611Snjl 659118611Snjl DbgPrint (ASL_PARSE_OUTPUT, "\n\n"); 660118611Snjl return Op; 661118611Snjl} 662118611Snjl 663118611Snjl 664118611Snjl/******************************************************************************* 665118611Snjl * 666118611Snjl * FUNCTION: TrLinkChildren 667118611Snjl * 668118611Snjl * PARAMETERS: Op - An existing parse node 669118611Snjl * NumChildren - Number of children to follow 670118611Snjl * ... - A list of child nodes to link to the new 671118611Snjl * node. NumChildren long. 672118611Snjl * 673118611Snjl * RETURN: The updated (linked) node 674118611Snjl * 675118611Snjl * DESCRIPTION: Link a group of nodes to an existing parse node 676118611Snjl * 677118611Snjl ******************************************************************************/ 678118611Snjl 679118611SnjlACPI_PARSE_OBJECT * 680118611SnjlTrLinkChildren ( 681118611Snjl ACPI_PARSE_OBJECT *Op, 682118611Snjl UINT32 NumChildren, 683118611Snjl ...) 684118611Snjl{ 685118611Snjl ACPI_PARSE_OBJECT *Child; 686118611Snjl ACPI_PARSE_OBJECT *PrevChild; 687118611Snjl va_list ap; 688118611Snjl UINT32 i; 689118611Snjl BOOLEAN FirstChild; 690118611Snjl 691118611Snjl 692118611Snjl va_start (ap, NumChildren); 693118611Snjl 694118611Snjl 695118611Snjl TrSetEndLineNumber (Op); 696118611Snjl 697118611Snjl DbgPrint (ASL_PARSE_OUTPUT, 698118611Snjl "\nLinkChildren Line [%d to %d] NewParent %p Child %d Op %s ", 699118611Snjl Op->Asl.LineNumber, Op->Asl.EndLine, 700118611Snjl Op, NumChildren, UtGetOpName(Op->Asl.ParseOpcode)); 701118611Snjl 702118611Snjl switch (Op->Asl.ParseOpcode) 703118611Snjl { 704118611Snjl case PARSEOP_DEFINITIONBLOCK: 705118611Snjl RootNode = Op; 706118611Snjl DbgPrint (ASL_PARSE_OUTPUT, "DEFINITION_BLOCK (Tree Completed)->"); 707118611Snjl break; 708118611Snjl 709118611Snjl case PARSEOP_OPERATIONREGION: 710118611Snjl DbgPrint (ASL_PARSE_OUTPUT, "OPREGION->"); 711118611Snjl break; 712118611Snjl 713118611Snjl case PARSEOP_OR: 714118611Snjl DbgPrint (ASL_PARSE_OUTPUT, "OR->"); 715118611Snjl break; 716118611Snjl 717118611Snjl default: 718118611Snjl /* Nothing to do for other opcodes */ 719118611Snjl break; 720118611Snjl } 721118611Snjl 722118611Snjl /* Link the new node to it's children */ 723118611Snjl 724118611Snjl PrevChild = NULL; 725118611Snjl FirstChild = TRUE; 726118611Snjl for (i = 0; i < NumChildren; i++) 727118611Snjl { 728118611Snjl Child = va_arg (ap, ACPI_PARSE_OBJECT *); 729118611Snjl 730118611Snjl if ((Child == PrevChild) && (Child != NULL)) 731118611Snjl { 732151937Sjkim AslError (ASL_WARNING, ASL_MSG_COMPILER_INTERNAL, Child, 733151937Sjkim "Child node list invalid"); 734118611Snjl return Op; 735118611Snjl } 736118611Snjl 737118611Snjl DbgPrint (ASL_PARSE_OUTPUT, "%p, ", Child); 738118611Snjl 739118611Snjl /* 740118611Snjl * If child is NULL, this means that an optional argument 741118611Snjl * was omitted. We must create a placeholder with a special 742118611Snjl * opcode (DEFAULT_ARG) so that the code generator will know 743118611Snjl * that it must emit the correct default for this argument 744118611Snjl */ 745118611Snjl if (!Child) 746118611Snjl { 747118611Snjl Child = TrAllocateNode (PARSEOP_DEFAULT_ARG); 748118611Snjl } 749118611Snjl 750118611Snjl /* Link first child to parent */ 751118611Snjl 752118611Snjl if (FirstChild) 753118611Snjl { 754118611Snjl FirstChild = FALSE; 755118611Snjl Op->Asl.Child = Child; 756118611Snjl } 757118611Snjl 758118611Snjl /* Point all children to parent */ 759118611Snjl 760118611Snjl Child->Asl.Parent = Op; 761118611Snjl 762118611Snjl /* Link children in a peer list */ 763118611Snjl 764118611Snjl if (PrevChild) 765118611Snjl { 766118611Snjl PrevChild->Asl.Next = Child; 767118611Snjl }; 768118611Snjl 769118611Snjl /* 770118611Snjl * This child might be a list, point all nodes in the list 771118611Snjl * to the same parent 772118611Snjl */ 773118611Snjl while (Child->Asl.Next) 774118611Snjl { 775118611Snjl Child = Child->Asl.Next; 776118611Snjl Child->Asl.Parent = Op; 777118611Snjl } 778118611Snjl PrevChild = Child; 779118611Snjl } 780118611Snjl va_end(ap); 781118611Snjl 782118611Snjl DbgPrint (ASL_PARSE_OUTPUT, "\n\n"); 783118611Snjl return Op; 784118611Snjl} 785118611Snjl 786118611Snjl 787118611Snjl/******************************************************************************* 788118611Snjl * 789118611Snjl * FUNCTION: TrLinkPeerNode 790118611Snjl * 791118611Snjl * PARAMETERS: Op1 - First peer 792118611Snjl * Op2 - Second peer 793118611Snjl * 794118611Snjl * RETURN: Op1 or the non-null node. 795118611Snjl * 796118611Snjl * DESCRIPTION: Link two nodes as peers. Handles cases where one peer is null. 797118611Snjl * 798118611Snjl ******************************************************************************/ 799118611Snjl 800118611SnjlACPI_PARSE_OBJECT * 801118611SnjlTrLinkPeerNode ( 802118611Snjl ACPI_PARSE_OBJECT *Op1, 803118611Snjl ACPI_PARSE_OBJECT *Op2) 804118611Snjl{ 805118611Snjl ACPI_PARSE_OBJECT *Next; 806118611Snjl 807118611Snjl 808118611Snjl DbgPrint (ASL_PARSE_OUTPUT, 809118611Snjl "\nLinkPeerNode: 1=%p (%s), 2=%p (%s)\n\n", 810118611Snjl Op1, Op1 ? UtGetOpName(Op1->Asl.ParseOpcode) : NULL, 811118611Snjl Op2, Op2 ? UtGetOpName(Op2->Asl.ParseOpcode) : NULL); 812118611Snjl 813118611Snjl 814118611Snjl if ((!Op1) && (!Op2)) 815118611Snjl { 816118611Snjl DbgPrint (ASL_PARSE_OUTPUT, "\nTwo Null nodes!\n"); 817118611Snjl return Op1; 818118611Snjl } 819118611Snjl 820118611Snjl /* If one of the nodes is null, just return the non-null node */ 821118611Snjl 822118611Snjl if (!Op2) 823118611Snjl { 824118611Snjl return Op1; 825118611Snjl } 826118611Snjl 827118611Snjl if (!Op1) 828118611Snjl { 829118611Snjl return Op2; 830118611Snjl } 831118611Snjl 832118611Snjl if (Op1 == Op2) 833118611Snjl { 834118611Snjl DbgPrint (ASL_DEBUG_OUTPUT, 835151937Sjkim "\n\n************* Internal error, linking node to itself %p\n\n\n", 836151937Sjkim Op1); 837151937Sjkim AslError (ASL_WARNING, ASL_MSG_COMPILER_INTERNAL, Op1, 838151937Sjkim "Linking node to itself"); 839118611Snjl return Op1; 840118611Snjl } 841118611Snjl 842118611Snjl Op1->Asl.Parent = Op2->Asl.Parent; 843118611Snjl 844118611Snjl /* 845118611Snjl * Op 1 may already have a peer list (such as an IF/ELSE pair), 846118611Snjl * so we must walk to the end of the list and attach the new 847118611Snjl * peer at the end 848118611Snjl */ 849118611Snjl Next = Op1; 850118611Snjl while (Next->Asl.Next) 851118611Snjl { 852118611Snjl Next = Next->Asl.Next; 853118611Snjl } 854118611Snjl 855118611Snjl Next->Asl.Next = Op2; 856118611Snjl return Op1; 857118611Snjl} 858118611Snjl 859118611Snjl 860118611Snjl/******************************************************************************* 861118611Snjl * 862118611Snjl * FUNCTION: TrLinkPeerNodes 863118611Snjl * 864118611Snjl * PARAMETERS: NumPeers - The number of nodes in the list to follow 865118611Snjl * ... - A list of nodes to link together as peers 866118611Snjl * 867118611Snjl * RETURN: The first node in the list (head of the peer list) 868118611Snjl * 869118611Snjl * DESCRIPTION: Link together an arbitrary number of peer nodes. 870118611Snjl * 871118611Snjl ******************************************************************************/ 872118611Snjl 873118611SnjlACPI_PARSE_OBJECT * 874118611SnjlTrLinkPeerNodes ( 875118611Snjl UINT32 NumPeers, 876118611Snjl ...) 877118611Snjl{ 878118611Snjl ACPI_PARSE_OBJECT *This; 879118611Snjl ACPI_PARSE_OBJECT *Next; 880118611Snjl va_list ap; 881118611Snjl UINT32 i; 882118611Snjl ACPI_PARSE_OBJECT *Start; 883118611Snjl 884118611Snjl 885118611Snjl DbgPrint (ASL_PARSE_OUTPUT, 886118611Snjl "\nLinkPeerNodes: (%d) ", NumPeers); 887118611Snjl 888118611Snjl va_start (ap, NumPeers); 889118611Snjl This = va_arg (ap, ACPI_PARSE_OBJECT *); 890118611Snjl Start = This; 891118611Snjl 892118611Snjl /* 893118611Snjl * Link all peers 894118611Snjl */ 895118611Snjl for (i = 0; i < (NumPeers -1); i++) 896118611Snjl { 897118611Snjl DbgPrint (ASL_PARSE_OUTPUT, "%d=%p ", (i+1), This); 898118611Snjl 899118611Snjl while (This->Asl.Next) 900118611Snjl { 901118611Snjl This = This->Asl.Next; 902118611Snjl } 903118611Snjl 904118611Snjl /* Get another peer node */ 905118611Snjl 906118611Snjl Next = va_arg (ap, ACPI_PARSE_OBJECT *); 907118611Snjl if (!Next) 908118611Snjl { 909118611Snjl Next = TrAllocateNode (PARSEOP_DEFAULT_ARG); 910118611Snjl } 911118611Snjl 912118611Snjl /* link new node to the current node */ 913118611Snjl 914118611Snjl This->Asl.Next = Next; 915118611Snjl This = Next; 916118611Snjl } 917118611Snjl 918118611Snjl DbgPrint (ASL_PARSE_OUTPUT,"\n\n"); 919118611Snjl return (Start); 920118611Snjl} 921118611Snjl 922118611Snjl 923118611Snjl/******************************************************************************* 924118611Snjl * 925118611Snjl * FUNCTION: TrLinkChildNode 926118611Snjl * 927118611Snjl * PARAMETERS: Op1 - Parent node 928118611Snjl * Op2 - Op to become a child 929118611Snjl * 930118611Snjl * RETURN: The parent node 931118611Snjl * 932118611Snjl * DESCRIPTION: Link two nodes together as a parent and child 933118611Snjl * 934118611Snjl ******************************************************************************/ 935118611Snjl 936118611SnjlACPI_PARSE_OBJECT * 937118611SnjlTrLinkChildNode ( 938118611Snjl ACPI_PARSE_OBJECT *Op1, 939118611Snjl ACPI_PARSE_OBJECT *Op2) 940118611Snjl{ 941118611Snjl ACPI_PARSE_OBJECT *Next; 942118611Snjl 943118611Snjl 944118611Snjl DbgPrint (ASL_PARSE_OUTPUT, 945118611Snjl "\nLinkChildNode: Parent=%p (%s), Child=%p (%s)\n\n", 946118611Snjl Op1, Op1 ? UtGetOpName(Op1->Asl.ParseOpcode): NULL, 947118611Snjl Op2, Op2 ? UtGetOpName(Op2->Asl.ParseOpcode): NULL); 948118611Snjl 949118611Snjl if (!Op1 || !Op2) 950118611Snjl { 951118611Snjl return Op1; 952118611Snjl } 953118611Snjl 954118611Snjl Op1->Asl.Child = Op2; 955118611Snjl 956118611Snjl /* Set the child and all peers of the child to point to the parent */ 957118611Snjl 958118611Snjl Next = Op2; 959118611Snjl while (Next) 960118611Snjl { 961118611Snjl Next->Asl.Parent = Op1; 962118611Snjl Next = Next->Asl.Next; 963118611Snjl } 964118611Snjl 965118611Snjl return Op1; 966118611Snjl} 967118611Snjl 968118611Snjl 969118611Snjl/******************************************************************************* 970118611Snjl * 971118611Snjl * FUNCTION: TrWalkParseTree 972118611Snjl * 973118611Snjl * PARAMETERS: Visitation - Type of walk 974118611Snjl * DescendingCallback - Called during tree descent 975118611Snjl * AscendingCallback - Called during tree ascent 976118611Snjl * Context - To be passed to the callbacks 977118611Snjl * 978118611Snjl * RETURN: Status from callback(s) 979118611Snjl * 980118611Snjl * DESCRIPTION: Walk the entire parse tree. 981118611Snjl * 982118611Snjl ******************************************************************************/ 983118611Snjl 984118611SnjlACPI_STATUS 985118611SnjlTrWalkParseTree ( 986118611Snjl ACPI_PARSE_OBJECT *Op, 987118611Snjl UINT32 Visitation, 988118611Snjl ASL_WALK_CALLBACK DescendingCallback, 989118611Snjl ASL_WALK_CALLBACK AscendingCallback, 990118611Snjl void *Context) 991118611Snjl{ 992118611Snjl UINT32 Level; 993118611Snjl BOOLEAN NodePreviouslyVisited; 994118611Snjl ACPI_PARSE_OBJECT *StartOp = Op; 995118611Snjl ACPI_STATUS Status; 996118611Snjl 997118611Snjl 998118611Snjl if (!RootNode) 999118611Snjl { 1000118611Snjl return (AE_OK); 1001118611Snjl } 1002118611Snjl 1003118611Snjl Level = 0; 1004118611Snjl NodePreviouslyVisited = FALSE; 1005118611Snjl 1006118611Snjl switch (Visitation) 1007118611Snjl { 1008118611Snjl case ASL_WALK_VISIT_DOWNWARD: 1009118611Snjl 1010118611Snjl while (Op) 1011118611Snjl { 1012118611Snjl if (!NodePreviouslyVisited) 1013118611Snjl { 1014151937Sjkim /* Let the callback process the node. */ 1015151937Sjkim 1016118611Snjl Status = DescendingCallback (Op, Level, Context); 1017118611Snjl if (ACPI_SUCCESS (Status)) 1018118611Snjl { 1019118611Snjl /* Visit children first, once */ 1020118611Snjl 1021118611Snjl if (Op->Asl.Child) 1022118611Snjl { 1023118611Snjl Level++; 1024118611Snjl Op = Op->Asl.Child; 1025118611Snjl continue; 1026118611Snjl } 1027118611Snjl } 1028118611Snjl else if (Status != AE_CTRL_DEPTH) 1029118611Snjl { 1030118611Snjl /* Exit immediately on any error */ 1031118611Snjl 1032118611Snjl return (Status); 1033118611Snjl } 1034118611Snjl } 1035118611Snjl 1036118611Snjl /* Terminate walk at start op */ 1037118611Snjl 1038118611Snjl if (Op == StartOp) 1039118611Snjl { 1040118611Snjl break; 1041118611Snjl } 1042118611Snjl 1043118611Snjl /* No more children, visit peers */ 1044118611Snjl 1045118611Snjl if (Op->Asl.Next) 1046118611Snjl { 1047118611Snjl Op = Op->Asl.Next; 1048118611Snjl NodePreviouslyVisited = FALSE; 1049118611Snjl } 1050118611Snjl else 1051118611Snjl { 1052118611Snjl /* No children or peers, re-visit parent */ 1053118611Snjl 1054118611Snjl if (Level != 0 ) 1055118611Snjl { 1056118611Snjl Level--; 1057118611Snjl } 1058118611Snjl Op = Op->Asl.Parent; 1059118611Snjl NodePreviouslyVisited = TRUE; 1060118611Snjl } 1061118611Snjl } 1062118611Snjl break; 1063118611Snjl 1064118611Snjl 1065118611Snjl case ASL_WALK_VISIT_UPWARD: 1066118611Snjl 1067118611Snjl while (Op) 1068118611Snjl { 1069118611Snjl /* Visit leaf node (no children) or parent node on return trip */ 1070118611Snjl 1071118611Snjl if ((!Op->Asl.Child) || 1072118611Snjl (NodePreviouslyVisited)) 1073118611Snjl { 1074151937Sjkim /* Let the callback process the node. */ 1075151937Sjkim 1076118611Snjl Status = AscendingCallback (Op, Level, Context); 1077118611Snjl if (ACPI_FAILURE (Status)) 1078118611Snjl { 1079118611Snjl return (Status); 1080118611Snjl } 1081118611Snjl } 1082118611Snjl else 1083118611Snjl { 1084118611Snjl /* Visit children first, once */ 1085118611Snjl 1086118611Snjl Level++; 1087118611Snjl Op = Op->Asl.Child; 1088118611Snjl continue; 1089118611Snjl } 1090118611Snjl 1091118611Snjl /* Terminate walk at start op */ 1092118611Snjl 1093118611Snjl if (Op == StartOp) 1094118611Snjl { 1095118611Snjl break; 1096118611Snjl } 1097118611Snjl 1098118611Snjl /* No more children, visit peers */ 1099118611Snjl 1100118611Snjl if (Op->Asl.Next) 1101118611Snjl { 1102118611Snjl Op = Op->Asl.Next; 1103118611Snjl NodePreviouslyVisited = FALSE; 1104118611Snjl } 1105118611Snjl else 1106118611Snjl { 1107118611Snjl /* No children or peers, re-visit parent */ 1108118611Snjl 1109118611Snjl if (Level != 0 ) 1110118611Snjl { 1111118611Snjl Level--; 1112118611Snjl } 1113118611Snjl Op = Op->Asl.Parent; 1114118611Snjl NodePreviouslyVisited = TRUE; 1115118611Snjl } 1116118611Snjl } 1117118611Snjl break; 1118118611Snjl 1119118611Snjl 1120118611Snjl case ASL_WALK_VISIT_TWICE: 1121118611Snjl 1122118611Snjl while (Op) 1123118611Snjl { 1124118611Snjl if (NodePreviouslyVisited) 1125118611Snjl { 1126118611Snjl Status = AscendingCallback (Op, Level, Context); 1127118611Snjl if (ACPI_FAILURE (Status)) 1128118611Snjl { 1129118611Snjl return (Status); 1130118611Snjl } 1131118611Snjl } 1132118611Snjl else 1133118611Snjl { 1134151937Sjkim /* Let the callback process the node. */ 1135151937Sjkim 1136118611Snjl Status = DescendingCallback (Op, Level, Context); 1137118611Snjl if (ACPI_SUCCESS (Status)) 1138118611Snjl { 1139118611Snjl /* Visit children first, once */ 1140118611Snjl 1141118611Snjl if (Op->Asl.Child) 1142118611Snjl { 1143118611Snjl Level++; 1144118611Snjl Op = Op->Asl.Child; 1145118611Snjl continue; 1146118611Snjl } 1147118611Snjl } 1148118611Snjl else if (Status != AE_CTRL_DEPTH) 1149118611Snjl { 1150118611Snjl /* Exit immediately on any error */ 1151118611Snjl 1152118611Snjl return (Status); 1153118611Snjl } 1154118611Snjl } 1155118611Snjl 1156118611Snjl /* Terminate walk at start op */ 1157118611Snjl 1158118611Snjl if (Op == StartOp) 1159118611Snjl { 1160118611Snjl break; 1161118611Snjl } 1162118611Snjl 1163118611Snjl /* No more children, visit peers */ 1164118611Snjl 1165118611Snjl if (Op->Asl.Next) 1166118611Snjl { 1167118611Snjl Op = Op->Asl.Next; 1168118611Snjl NodePreviouslyVisited = FALSE; 1169118611Snjl } 1170118611Snjl else 1171118611Snjl { 1172118611Snjl /* No children or peers, re-visit parent */ 1173118611Snjl 1174118611Snjl if (Level != 0 ) 1175118611Snjl { 1176118611Snjl Level--; 1177118611Snjl } 1178118611Snjl Op = Op->Asl.Parent; 1179118611Snjl NodePreviouslyVisited = TRUE; 1180118611Snjl } 1181118611Snjl } 1182118611Snjl break; 1183118611Snjl 1184118611Snjl default: 1185118611Snjl /* No other types supported */ 1186118611Snjl break; 1187118611Snjl } 1188118611Snjl 1189118611Snjl /* If we get here, the walk completed with no errors */ 1190118611Snjl 1191118611Snjl return (AE_OK); 1192118611Snjl} 1193118611Snjl 1194118611Snjl 1195