1*a159c266SJung-uk Kim /****************************************************************************** 2*a159c266SJung-uk Kim * 3*a159c266SJung-uk Kim * Module Name: pstree - Parser op tree manipulation/traversal/search 4*a159c266SJung-uk Kim * 5*a159c266SJung-uk Kim *****************************************************************************/ 6*a159c266SJung-uk Kim 7*a159c266SJung-uk Kim /* 8*a159c266SJung-uk Kim * Copyright (C) 2000 - 2012, Intel Corp. 9*a159c266SJung-uk Kim * All rights reserved. 10*a159c266SJung-uk Kim * 11*a159c266SJung-uk Kim * Redistribution and use in source and binary forms, with or without 12*a159c266SJung-uk Kim * modification, are permitted provided that the following conditions 13*a159c266SJung-uk Kim * are met: 14*a159c266SJung-uk Kim * 1. Redistributions of source code must retain the above copyright 15*a159c266SJung-uk Kim * notice, this list of conditions, and the following disclaimer, 16*a159c266SJung-uk Kim * without modification. 17*a159c266SJung-uk Kim * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18*a159c266SJung-uk Kim * substantially similar to the "NO WARRANTY" disclaimer below 19*a159c266SJung-uk Kim * ("Disclaimer") and any redistribution must be conditioned upon 20*a159c266SJung-uk Kim * including a substantially similar Disclaimer requirement for further 21*a159c266SJung-uk Kim * binary redistribution. 22*a159c266SJung-uk Kim * 3. Neither the names of the above-listed copyright holders nor the names 23*a159c266SJung-uk Kim * of any contributors may be used to endorse or promote products derived 24*a159c266SJung-uk Kim * from this software without specific prior written permission. 25*a159c266SJung-uk Kim * 26*a159c266SJung-uk Kim * Alternatively, this software may be distributed under the terms of the 27*a159c266SJung-uk Kim * GNU General Public License ("GPL") version 2 as published by the Free 28*a159c266SJung-uk Kim * Software Foundation. 29*a159c266SJung-uk Kim * 30*a159c266SJung-uk Kim * NO WARRANTY 31*a159c266SJung-uk Kim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32*a159c266SJung-uk Kim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33*a159c266SJung-uk Kim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34*a159c266SJung-uk Kim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35*a159c266SJung-uk Kim * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36*a159c266SJung-uk Kim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37*a159c266SJung-uk Kim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38*a159c266SJung-uk Kim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39*a159c266SJung-uk Kim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40*a159c266SJung-uk Kim * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41*a159c266SJung-uk Kim * POSSIBILITY OF SUCH DAMAGES. 42*a159c266SJung-uk Kim */ 43*a159c266SJung-uk Kim 44*a159c266SJung-uk Kim 45*a159c266SJung-uk Kim #define __PSTREE_C__ 46*a159c266SJung-uk Kim 47*a159c266SJung-uk Kim #include <contrib/dev/acpica/include/acpi.h> 48*a159c266SJung-uk Kim #include <contrib/dev/acpica/include/accommon.h> 49*a159c266SJung-uk Kim #include <contrib/dev/acpica/include/acparser.h> 50*a159c266SJung-uk Kim #include <contrib/dev/acpica/include/amlcode.h> 51*a159c266SJung-uk Kim 52*a159c266SJung-uk Kim #define _COMPONENT ACPI_PARSER 53*a159c266SJung-uk Kim ACPI_MODULE_NAME ("pstree") 54*a159c266SJung-uk Kim 55*a159c266SJung-uk Kim /* Local prototypes */ 56*a159c266SJung-uk Kim 57*a159c266SJung-uk Kim #ifdef ACPI_OBSOLETE_FUNCTIONS 58*a159c266SJung-uk Kim ACPI_PARSE_OBJECT * 59*a159c266SJung-uk Kim AcpiPsGetChild ( 60*a159c266SJung-uk Kim ACPI_PARSE_OBJECT *op); 61*a159c266SJung-uk Kim #endif 62*a159c266SJung-uk Kim 63*a159c266SJung-uk Kim 64*a159c266SJung-uk Kim /******************************************************************************* 65*a159c266SJung-uk Kim * 66*a159c266SJung-uk Kim * FUNCTION: AcpiPsGetArg 67*a159c266SJung-uk Kim * 68*a159c266SJung-uk Kim * PARAMETERS: Op - Get an argument for this op 69*a159c266SJung-uk Kim * Argn - Nth argument to get 70*a159c266SJung-uk Kim * 71*a159c266SJung-uk Kim * RETURN: The argument (as an Op object). NULL if argument does not exist 72*a159c266SJung-uk Kim * 73*a159c266SJung-uk Kim * DESCRIPTION: Get the specified op's argument. 74*a159c266SJung-uk Kim * 75*a159c266SJung-uk Kim ******************************************************************************/ 76*a159c266SJung-uk Kim 77*a159c266SJung-uk Kim ACPI_PARSE_OBJECT * 78*a159c266SJung-uk Kim AcpiPsGetArg ( 79*a159c266SJung-uk Kim ACPI_PARSE_OBJECT *Op, 80*a159c266SJung-uk Kim UINT32 Argn) 81*a159c266SJung-uk Kim { 82*a159c266SJung-uk Kim ACPI_PARSE_OBJECT *Arg = NULL; 83*a159c266SJung-uk Kim const ACPI_OPCODE_INFO *OpInfo; 84*a159c266SJung-uk Kim 85*a159c266SJung-uk Kim 86*a159c266SJung-uk Kim ACPI_FUNCTION_ENTRY (); 87*a159c266SJung-uk Kim 88*a159c266SJung-uk Kim /* 89*a159c266SJung-uk Kim if (Op->Common.AmlOpcode == AML_INT_CONNECTION_OP) 90*a159c266SJung-uk Kim { 91*a159c266SJung-uk Kim return (Op->Common.Value.Arg); 92*a159c266SJung-uk Kim } 93*a159c266SJung-uk Kim */ 94*a159c266SJung-uk Kim /* Get the info structure for this opcode */ 95*a159c266SJung-uk Kim 96*a159c266SJung-uk Kim OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode); 97*a159c266SJung-uk Kim if (OpInfo->Class == AML_CLASS_UNKNOWN) 98*a159c266SJung-uk Kim { 99*a159c266SJung-uk Kim /* Invalid opcode or ASCII character */ 100*a159c266SJung-uk Kim 101*a159c266SJung-uk Kim return (NULL); 102*a159c266SJung-uk Kim } 103*a159c266SJung-uk Kim 104*a159c266SJung-uk Kim /* Check if this opcode requires argument sub-objects */ 105*a159c266SJung-uk Kim 106*a159c266SJung-uk Kim if (!(OpInfo->Flags & AML_HAS_ARGS)) 107*a159c266SJung-uk Kim { 108*a159c266SJung-uk Kim /* Has no linked argument objects */ 109*a159c266SJung-uk Kim 110*a159c266SJung-uk Kim return (NULL); 111*a159c266SJung-uk Kim } 112*a159c266SJung-uk Kim 113*a159c266SJung-uk Kim /* Get the requested argument object */ 114*a159c266SJung-uk Kim 115*a159c266SJung-uk Kim Arg = Op->Common.Value.Arg; 116*a159c266SJung-uk Kim while (Arg && Argn) 117*a159c266SJung-uk Kim { 118*a159c266SJung-uk Kim Argn--; 119*a159c266SJung-uk Kim Arg = Arg->Common.Next; 120*a159c266SJung-uk Kim } 121*a159c266SJung-uk Kim 122*a159c266SJung-uk Kim return (Arg); 123*a159c266SJung-uk Kim } 124*a159c266SJung-uk Kim 125*a159c266SJung-uk Kim 126*a159c266SJung-uk Kim /******************************************************************************* 127*a159c266SJung-uk Kim * 128*a159c266SJung-uk Kim * FUNCTION: AcpiPsAppendArg 129*a159c266SJung-uk Kim * 130*a159c266SJung-uk Kim * PARAMETERS: Op - Append an argument to this Op. 131*a159c266SJung-uk Kim * Arg - Argument Op to append 132*a159c266SJung-uk Kim * 133*a159c266SJung-uk Kim * RETURN: None. 134*a159c266SJung-uk Kim * 135*a159c266SJung-uk Kim * DESCRIPTION: Append an argument to an op's argument list (a NULL arg is OK) 136*a159c266SJung-uk Kim * 137*a159c266SJung-uk Kim ******************************************************************************/ 138*a159c266SJung-uk Kim 139*a159c266SJung-uk Kim void 140*a159c266SJung-uk Kim AcpiPsAppendArg ( 141*a159c266SJung-uk Kim ACPI_PARSE_OBJECT *Op, 142*a159c266SJung-uk Kim ACPI_PARSE_OBJECT *Arg) 143*a159c266SJung-uk Kim { 144*a159c266SJung-uk Kim ACPI_PARSE_OBJECT *PrevArg; 145*a159c266SJung-uk Kim const ACPI_OPCODE_INFO *OpInfo; 146*a159c266SJung-uk Kim 147*a159c266SJung-uk Kim 148*a159c266SJung-uk Kim ACPI_FUNCTION_ENTRY (); 149*a159c266SJung-uk Kim 150*a159c266SJung-uk Kim 151*a159c266SJung-uk Kim if (!Op) 152*a159c266SJung-uk Kim { 153*a159c266SJung-uk Kim return; 154*a159c266SJung-uk Kim } 155*a159c266SJung-uk Kim 156*a159c266SJung-uk Kim /* Get the info structure for this opcode */ 157*a159c266SJung-uk Kim 158*a159c266SJung-uk Kim OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode); 159*a159c266SJung-uk Kim if (OpInfo->Class == AML_CLASS_UNKNOWN) 160*a159c266SJung-uk Kim { 161*a159c266SJung-uk Kim /* Invalid opcode */ 162*a159c266SJung-uk Kim 163*a159c266SJung-uk Kim ACPI_ERROR ((AE_INFO, "Invalid AML Opcode: 0x%2.2X", 164*a159c266SJung-uk Kim Op->Common.AmlOpcode)); 165*a159c266SJung-uk Kim return; 166*a159c266SJung-uk Kim } 167*a159c266SJung-uk Kim 168*a159c266SJung-uk Kim /* Check if this opcode requires argument sub-objects */ 169*a159c266SJung-uk Kim 170*a159c266SJung-uk Kim if (!(OpInfo->Flags & AML_HAS_ARGS)) 171*a159c266SJung-uk Kim { 172*a159c266SJung-uk Kim /* Has no linked argument objects */ 173*a159c266SJung-uk Kim 174*a159c266SJung-uk Kim return; 175*a159c266SJung-uk Kim } 176*a159c266SJung-uk Kim 177*a159c266SJung-uk Kim /* Append the argument to the linked argument list */ 178*a159c266SJung-uk Kim 179*a159c266SJung-uk Kim if (Op->Common.Value.Arg) 180*a159c266SJung-uk Kim { 181*a159c266SJung-uk Kim /* Append to existing argument list */ 182*a159c266SJung-uk Kim 183*a159c266SJung-uk Kim PrevArg = Op->Common.Value.Arg; 184*a159c266SJung-uk Kim while (PrevArg->Common.Next) 185*a159c266SJung-uk Kim { 186*a159c266SJung-uk Kim PrevArg = PrevArg->Common.Next; 187*a159c266SJung-uk Kim } 188*a159c266SJung-uk Kim PrevArg->Common.Next = Arg; 189*a159c266SJung-uk Kim } 190*a159c266SJung-uk Kim else 191*a159c266SJung-uk Kim { 192*a159c266SJung-uk Kim /* No argument list, this will be the first argument */ 193*a159c266SJung-uk Kim 194*a159c266SJung-uk Kim Op->Common.Value.Arg = Arg; 195*a159c266SJung-uk Kim } 196*a159c266SJung-uk Kim 197*a159c266SJung-uk Kim /* Set the parent in this arg and any args linked after it */ 198*a159c266SJung-uk Kim 199*a159c266SJung-uk Kim while (Arg) 200*a159c266SJung-uk Kim { 201*a159c266SJung-uk Kim Arg->Common.Parent = Op; 202*a159c266SJung-uk Kim Arg = Arg->Common.Next; 203*a159c266SJung-uk Kim 204*a159c266SJung-uk Kim Op->Common.ArgListLength++; 205*a159c266SJung-uk Kim } 206*a159c266SJung-uk Kim } 207*a159c266SJung-uk Kim 208*a159c266SJung-uk Kim 209*a159c266SJung-uk Kim /******************************************************************************* 210*a159c266SJung-uk Kim * 211*a159c266SJung-uk Kim * FUNCTION: AcpiPsGetDepthNext 212*a159c266SJung-uk Kim * 213*a159c266SJung-uk Kim * PARAMETERS: Origin - Root of subtree to search 214*a159c266SJung-uk Kim * Op - Last (previous) Op that was found 215*a159c266SJung-uk Kim * 216*a159c266SJung-uk Kim * RETURN: Next Op found in the search. 217*a159c266SJung-uk Kim * 218*a159c266SJung-uk Kim * DESCRIPTION: Get next op in tree (walking the tree in depth-first order) 219*a159c266SJung-uk Kim * Return NULL when reaching "origin" or when walking up from root 220*a159c266SJung-uk Kim * 221*a159c266SJung-uk Kim ******************************************************************************/ 222*a159c266SJung-uk Kim 223*a159c266SJung-uk Kim ACPI_PARSE_OBJECT * 224*a159c266SJung-uk Kim AcpiPsGetDepthNext ( 225*a159c266SJung-uk Kim ACPI_PARSE_OBJECT *Origin, 226*a159c266SJung-uk Kim ACPI_PARSE_OBJECT *Op) 227*a159c266SJung-uk Kim { 228*a159c266SJung-uk Kim ACPI_PARSE_OBJECT *Next = NULL; 229*a159c266SJung-uk Kim ACPI_PARSE_OBJECT *Parent; 230*a159c266SJung-uk Kim ACPI_PARSE_OBJECT *Arg; 231*a159c266SJung-uk Kim 232*a159c266SJung-uk Kim 233*a159c266SJung-uk Kim ACPI_FUNCTION_ENTRY (); 234*a159c266SJung-uk Kim 235*a159c266SJung-uk Kim 236*a159c266SJung-uk Kim if (!Op) 237*a159c266SJung-uk Kim { 238*a159c266SJung-uk Kim return (NULL); 239*a159c266SJung-uk Kim } 240*a159c266SJung-uk Kim 241*a159c266SJung-uk Kim /* Look for an argument or child */ 242*a159c266SJung-uk Kim 243*a159c266SJung-uk Kim Next = AcpiPsGetArg (Op, 0); 244*a159c266SJung-uk Kim if (Next) 245*a159c266SJung-uk Kim { 246*a159c266SJung-uk Kim return (Next); 247*a159c266SJung-uk Kim } 248*a159c266SJung-uk Kim 249*a159c266SJung-uk Kim /* Look for a sibling */ 250*a159c266SJung-uk Kim 251*a159c266SJung-uk Kim Next = Op->Common.Next; 252*a159c266SJung-uk Kim if (Next) 253*a159c266SJung-uk Kim { 254*a159c266SJung-uk Kim return (Next); 255*a159c266SJung-uk Kim } 256*a159c266SJung-uk Kim 257*a159c266SJung-uk Kim /* Look for a sibling of parent */ 258*a159c266SJung-uk Kim 259*a159c266SJung-uk Kim Parent = Op->Common.Parent; 260*a159c266SJung-uk Kim 261*a159c266SJung-uk Kim while (Parent) 262*a159c266SJung-uk Kim { 263*a159c266SJung-uk Kim Arg = AcpiPsGetArg (Parent, 0); 264*a159c266SJung-uk Kim while (Arg && (Arg != Origin) && (Arg != Op)) 265*a159c266SJung-uk Kim { 266*a159c266SJung-uk Kim Arg = Arg->Common.Next; 267*a159c266SJung-uk Kim } 268*a159c266SJung-uk Kim 269*a159c266SJung-uk Kim if (Arg == Origin) 270*a159c266SJung-uk Kim { 271*a159c266SJung-uk Kim /* Reached parent of origin, end search */ 272*a159c266SJung-uk Kim 273*a159c266SJung-uk Kim return (NULL); 274*a159c266SJung-uk Kim } 275*a159c266SJung-uk Kim 276*a159c266SJung-uk Kim if (Parent->Common.Next) 277*a159c266SJung-uk Kim { 278*a159c266SJung-uk Kim /* Found sibling of parent */ 279*a159c266SJung-uk Kim 280*a159c266SJung-uk Kim return (Parent->Common.Next); 281*a159c266SJung-uk Kim } 282*a159c266SJung-uk Kim 283*a159c266SJung-uk Kim Op = Parent; 284*a159c266SJung-uk Kim Parent = Parent->Common.Parent; 285*a159c266SJung-uk Kim } 286*a159c266SJung-uk Kim 287*a159c266SJung-uk Kim return (Next); 288*a159c266SJung-uk Kim } 289*a159c266SJung-uk Kim 290*a159c266SJung-uk Kim 291*a159c266SJung-uk Kim #ifdef ACPI_OBSOLETE_FUNCTIONS 292*a159c266SJung-uk Kim /******************************************************************************* 293*a159c266SJung-uk Kim * 294*a159c266SJung-uk Kim * FUNCTION: AcpiPsGetChild 295*a159c266SJung-uk Kim * 296*a159c266SJung-uk Kim * PARAMETERS: Op - Get the child of this Op 297*a159c266SJung-uk Kim * 298*a159c266SJung-uk Kim * RETURN: Child Op, Null if none is found. 299*a159c266SJung-uk Kim * 300*a159c266SJung-uk Kim * DESCRIPTION: Get op's children or NULL if none 301*a159c266SJung-uk Kim * 302*a159c266SJung-uk Kim ******************************************************************************/ 303*a159c266SJung-uk Kim 304*a159c266SJung-uk Kim ACPI_PARSE_OBJECT * 305*a159c266SJung-uk Kim AcpiPsGetChild ( 306*a159c266SJung-uk Kim ACPI_PARSE_OBJECT *Op) 307*a159c266SJung-uk Kim { 308*a159c266SJung-uk Kim ACPI_PARSE_OBJECT *Child = NULL; 309*a159c266SJung-uk Kim 310*a159c266SJung-uk Kim 311*a159c266SJung-uk Kim ACPI_FUNCTION_ENTRY (); 312*a159c266SJung-uk Kim 313*a159c266SJung-uk Kim 314*a159c266SJung-uk Kim switch (Op->Common.AmlOpcode) 315*a159c266SJung-uk Kim { 316*a159c266SJung-uk Kim case AML_SCOPE_OP: 317*a159c266SJung-uk Kim case AML_ELSE_OP: 318*a159c266SJung-uk Kim case AML_DEVICE_OP: 319*a159c266SJung-uk Kim case AML_THERMAL_ZONE_OP: 320*a159c266SJung-uk Kim case AML_INT_METHODCALL_OP: 321*a159c266SJung-uk Kim 322*a159c266SJung-uk Kim Child = AcpiPsGetArg (Op, 0); 323*a159c266SJung-uk Kim break; 324*a159c266SJung-uk Kim 325*a159c266SJung-uk Kim 326*a159c266SJung-uk Kim case AML_BUFFER_OP: 327*a159c266SJung-uk Kim case AML_PACKAGE_OP: 328*a159c266SJung-uk Kim case AML_METHOD_OP: 329*a159c266SJung-uk Kim case AML_IF_OP: 330*a159c266SJung-uk Kim case AML_WHILE_OP: 331*a159c266SJung-uk Kim case AML_FIELD_OP: 332*a159c266SJung-uk Kim 333*a159c266SJung-uk Kim Child = AcpiPsGetArg (Op, 1); 334*a159c266SJung-uk Kim break; 335*a159c266SJung-uk Kim 336*a159c266SJung-uk Kim 337*a159c266SJung-uk Kim case AML_POWER_RES_OP: 338*a159c266SJung-uk Kim case AML_INDEX_FIELD_OP: 339*a159c266SJung-uk Kim 340*a159c266SJung-uk Kim Child = AcpiPsGetArg (Op, 2); 341*a159c266SJung-uk Kim break; 342*a159c266SJung-uk Kim 343*a159c266SJung-uk Kim 344*a159c266SJung-uk Kim case AML_PROCESSOR_OP: 345*a159c266SJung-uk Kim case AML_BANK_FIELD_OP: 346*a159c266SJung-uk Kim 347*a159c266SJung-uk Kim Child = AcpiPsGetArg (Op, 3); 348*a159c266SJung-uk Kim break; 349*a159c266SJung-uk Kim 350*a159c266SJung-uk Kim 351*a159c266SJung-uk Kim default: 352*a159c266SJung-uk Kim /* All others have no children */ 353*a159c266SJung-uk Kim break; 354*a159c266SJung-uk Kim } 355*a159c266SJung-uk Kim 356*a159c266SJung-uk Kim return (Child); 357*a159c266SJung-uk Kim } 358*a159c266SJung-uk Kim #endif 359*a159c266SJung-uk Kim 360*a159c266SJung-uk Kim 361