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