167754Smsmith/****************************************************************************** 267754Smsmith * 367754Smsmith * Module Name: pstree - Parser op tree manipulation/traversal/search 467754Smsmith * 567754Smsmith *****************************************************************************/ 667754Smsmith 7217365Sjkim/* 8306536Sjkim * Copyright (C) 2000 - 2016, Intel Corp. 970243Smsmith * All rights reserved. 1067754Smsmith * 11217365Sjkim * Redistribution and use in source and binary forms, with or without 12217365Sjkim * modification, are permitted provided that the following conditions 13217365Sjkim * are met: 14217365Sjkim * 1. Redistributions of source code must retain the above copyright 15217365Sjkim * notice, this list of conditions, and the following disclaimer, 16217365Sjkim * without modification. 17217365Sjkim * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18217365Sjkim * substantially similar to the "NO WARRANTY" disclaimer below 19217365Sjkim * ("Disclaimer") and any redistribution must be conditioned upon 20217365Sjkim * including a substantially similar Disclaimer requirement for further 21217365Sjkim * binary redistribution. 22217365Sjkim * 3. Neither the names of the above-listed copyright holders nor the names 23217365Sjkim * of any contributors may be used to endorse or promote products derived 24217365Sjkim * from this software without specific prior written permission. 2567754Smsmith * 26217365Sjkim * Alternatively, this software may be distributed under the terms of the 27217365Sjkim * GNU General Public License ("GPL") version 2 as published by the Free 28217365Sjkim * Software Foundation. 2967754Smsmith * 30217365Sjkim * NO WARRANTY 31217365Sjkim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32217365Sjkim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33217365Sjkim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34217365Sjkim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35217365Sjkim * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36217365Sjkim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37217365Sjkim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38217365Sjkim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39217365Sjkim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40217365Sjkim * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41217365Sjkim * POSSIBILITY OF SUCH DAMAGES. 42217365Sjkim */ 4367754Smsmith 44193341Sjkim#include <contrib/dev/acpica/include/acpi.h> 45193341Sjkim#include <contrib/dev/acpica/include/accommon.h> 46193341Sjkim#include <contrib/dev/acpica/include/acparser.h> 47193341Sjkim#include <contrib/dev/acpica/include/amlcode.h> 4867754Smsmith 4977424Smsmith#define _COMPONENT ACPI_PARSER 5091116Smsmith ACPI_MODULE_NAME ("pstree") 5167754Smsmith 52151937Sjkim/* Local prototypes */ 5367754Smsmith 54151937Sjkim#ifdef ACPI_OBSOLETE_FUNCTIONS 55151937SjkimACPI_PARSE_OBJECT * 56151937SjkimAcpiPsGetChild ( 57151937Sjkim ACPI_PARSE_OBJECT *op); 58151937Sjkim#endif 59151937Sjkim 60151937Sjkim 6167754Smsmith/******************************************************************************* 6267754Smsmith * 6367754Smsmith * FUNCTION: AcpiPsGetArg 6467754Smsmith * 6567754Smsmith * PARAMETERS: Op - Get an argument for this op 6667754Smsmith * Argn - Nth argument to get 6767754Smsmith * 68151937Sjkim * RETURN: The argument (as an Op object). NULL if argument does not exist 6967754Smsmith * 7067754Smsmith * DESCRIPTION: Get the specified op's argument. 7167754Smsmith * 7267754Smsmith ******************************************************************************/ 7367754Smsmith 7467754SmsmithACPI_PARSE_OBJECT * 7567754SmsmithAcpiPsGetArg ( 7667754Smsmith ACPI_PARSE_OBJECT *Op, 7767754Smsmith UINT32 Argn) 7867754Smsmith{ 7967754Smsmith ACPI_PARSE_OBJECT *Arg = NULL; 8083174Smsmith const ACPI_OPCODE_INFO *OpInfo; 8167754Smsmith 8267754Smsmith 8391116Smsmith ACPI_FUNCTION_ENTRY (); 8483174Smsmith 85228110Sjkim/* 86228110Sjkim if (Op->Common.AmlOpcode == AML_INT_CONNECTION_OP) 87228110Sjkim { 88228110Sjkim return (Op->Common.Value.Arg); 89228110Sjkim } 90228110Sjkim*/ 9167754Smsmith /* Get the info structure for this opcode */ 9267754Smsmith 9399679Siwasaki OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode); 9485756Smsmith if (OpInfo->Class == AML_CLASS_UNKNOWN) 9567754Smsmith { 9667754Smsmith /* Invalid opcode or ASCII character */ 9767754Smsmith 9867754Smsmith return (NULL); 9967754Smsmith } 10067754Smsmith 10167754Smsmith /* Check if this opcode requires argument sub-objects */ 10267754Smsmith 10385756Smsmith if (!(OpInfo->Flags & AML_HAS_ARGS)) 10467754Smsmith { 10567754Smsmith /* Has no linked argument objects */ 10667754Smsmith 10767754Smsmith return (NULL); 10867754Smsmith } 10967754Smsmith 11067754Smsmith /* Get the requested argument object */ 11167754Smsmith 11299679Siwasaki Arg = Op->Common.Value.Arg; 11367754Smsmith while (Arg && Argn) 11467754Smsmith { 11567754Smsmith Argn--; 11699679Siwasaki Arg = Arg->Common.Next; 11767754Smsmith } 11867754Smsmith 11967754Smsmith return (Arg); 12067754Smsmith} 12167754Smsmith 12267754Smsmith 12367754Smsmith/******************************************************************************* 12467754Smsmith * 12567754Smsmith * FUNCTION: AcpiPsAppendArg 12667754Smsmith * 12767754Smsmith * PARAMETERS: Op - Append an argument to this Op. 12867754Smsmith * Arg - Argument Op to append 12967754Smsmith * 13067754Smsmith * RETURN: None. 13167754Smsmith * 13267754Smsmith * DESCRIPTION: Append an argument to an op's argument list (a NULL arg is OK) 13367754Smsmith * 13467754Smsmith ******************************************************************************/ 13567754Smsmith 13667754Smsmithvoid 13767754SmsmithAcpiPsAppendArg ( 13867754Smsmith ACPI_PARSE_OBJECT *Op, 13967754Smsmith ACPI_PARSE_OBJECT *Arg) 14067754Smsmith{ 14167754Smsmith ACPI_PARSE_OBJECT *PrevArg; 14283174Smsmith const ACPI_OPCODE_INFO *OpInfo; 14367754Smsmith 14467754Smsmith 14591116Smsmith ACPI_FUNCTION_ENTRY (); 14683174Smsmith 14783174Smsmith 14867754Smsmith if (!Op) 14967754Smsmith { 15067754Smsmith return; 15167754Smsmith } 15267754Smsmith 15367754Smsmith /* Get the info structure for this opcode */ 15467754Smsmith 15599679Siwasaki OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode); 15685756Smsmith if (OpInfo->Class == AML_CLASS_UNKNOWN) 15767754Smsmith { 15867754Smsmith /* Invalid opcode */ 15967754Smsmith 160167802Sjkim ACPI_ERROR ((AE_INFO, "Invalid AML Opcode: 0x%2.2X", 16199679Siwasaki Op->Common.AmlOpcode)); 16267754Smsmith return; 16367754Smsmith } 16467754Smsmith 16567754Smsmith /* Check if this opcode requires argument sub-objects */ 16667754Smsmith 16785756Smsmith if (!(OpInfo->Flags & AML_HAS_ARGS)) 16867754Smsmith { 16967754Smsmith /* Has no linked argument objects */ 17067754Smsmith 17167754Smsmith return; 17267754Smsmith } 17367754Smsmith 17467754Smsmith /* Append the argument to the linked argument list */ 17567754Smsmith 17699679Siwasaki if (Op->Common.Value.Arg) 17767754Smsmith { 17867754Smsmith /* Append to existing argument list */ 17967754Smsmith 18099679Siwasaki PrevArg = Op->Common.Value.Arg; 18199679Siwasaki while (PrevArg->Common.Next) 18267754Smsmith { 18399679Siwasaki PrevArg = PrevArg->Common.Next; 18467754Smsmith } 18599679Siwasaki PrevArg->Common.Next = Arg; 18667754Smsmith } 18767754Smsmith else 18867754Smsmith { 18967754Smsmith /* No argument list, this will be the first argument */ 19067754Smsmith 19199679Siwasaki Op->Common.Value.Arg = Arg; 19267754Smsmith } 19367754Smsmith 19467754Smsmith /* Set the parent in this arg and any args linked after it */ 19567754Smsmith 19667754Smsmith while (Arg) 19767754Smsmith { 19899679Siwasaki Arg->Common.Parent = Op; 19999679Siwasaki Arg = Arg->Common.Next; 200167802Sjkim 201167802Sjkim Op->Common.ArgListLength++; 20267754Smsmith } 20367754Smsmith} 20467754Smsmith 20567754Smsmith 20667754Smsmith/******************************************************************************* 20767754Smsmith * 20867754Smsmith * FUNCTION: AcpiPsGetDepthNext 20967754Smsmith * 21067754Smsmith * PARAMETERS: Origin - Root of subtree to search 21167754Smsmith * Op - Last (previous) Op that was found 21267754Smsmith * 21367754Smsmith * RETURN: Next Op found in the search. 21467754Smsmith * 21567754Smsmith * DESCRIPTION: Get next op in tree (walking the tree in depth-first order) 21667754Smsmith * Return NULL when reaching "origin" or when walking up from root 21767754Smsmith * 21867754Smsmith ******************************************************************************/ 21967754Smsmith 22067754SmsmithACPI_PARSE_OBJECT * 22167754SmsmithAcpiPsGetDepthNext ( 22267754Smsmith ACPI_PARSE_OBJECT *Origin, 22367754Smsmith ACPI_PARSE_OBJECT *Op) 22467754Smsmith{ 22567754Smsmith ACPI_PARSE_OBJECT *Next = NULL; 22667754Smsmith ACPI_PARSE_OBJECT *Parent; 22767754Smsmith ACPI_PARSE_OBJECT *Arg; 22867754Smsmith 22967754Smsmith 23091116Smsmith ACPI_FUNCTION_ENTRY (); 23183174Smsmith 23283174Smsmith 23367754Smsmith if (!Op) 23467754Smsmith { 23567754Smsmith return (NULL); 23667754Smsmith } 23767754Smsmith 238151937Sjkim /* Look for an argument or child */ 23967754Smsmith 24067754Smsmith Next = AcpiPsGetArg (Op, 0); 24167754Smsmith if (Next) 24267754Smsmith { 24367754Smsmith return (Next); 24467754Smsmith } 24567754Smsmith 246151937Sjkim /* Look for a sibling */ 24767754Smsmith 24899679Siwasaki Next = Op->Common.Next; 24967754Smsmith if (Next) 25067754Smsmith { 25167754Smsmith return (Next); 25267754Smsmith } 25367754Smsmith 254151937Sjkim /* Look for a sibling of parent */ 25567754Smsmith 25699679Siwasaki Parent = Op->Common.Parent; 25767754Smsmith 25867754Smsmith while (Parent) 25967754Smsmith { 26067754Smsmith Arg = AcpiPsGetArg (Parent, 0); 26167754Smsmith while (Arg && (Arg != Origin) && (Arg != Op)) 26267754Smsmith { 26399679Siwasaki Arg = Arg->Common.Next; 26467754Smsmith } 26567754Smsmith 26667754Smsmith if (Arg == Origin) 26767754Smsmith { 268151937Sjkim /* Reached parent of origin, end search */ 26967754Smsmith 27067754Smsmith return (NULL); 27167754Smsmith } 27267754Smsmith 27399679Siwasaki if (Parent->Common.Next) 27467754Smsmith { 275151937Sjkim /* Found sibling of parent */ 27699679Siwasaki 27799679Siwasaki return (Parent->Common.Next); 27867754Smsmith } 27967754Smsmith 28067754Smsmith Op = Parent; 28199679Siwasaki Parent = Parent->Common.Parent; 28267754Smsmith } 28367754Smsmith 28467754Smsmith return (Next); 28567754Smsmith} 28667754Smsmith 28767754Smsmith 288151937Sjkim#ifdef ACPI_OBSOLETE_FUNCTIONS 289151937Sjkim/******************************************************************************* 290151937Sjkim * 291151937Sjkim * FUNCTION: AcpiPsGetChild 292151937Sjkim * 293151937Sjkim * PARAMETERS: Op - Get the child of this Op 294151937Sjkim * 295151937Sjkim * RETURN: Child Op, Null if none is found. 296151937Sjkim * 297151937Sjkim * DESCRIPTION: Get op's children or NULL if none 298151937Sjkim * 299151937Sjkim ******************************************************************************/ 300151937Sjkim 301151937SjkimACPI_PARSE_OBJECT * 302151937SjkimAcpiPsGetChild ( 303151937Sjkim ACPI_PARSE_OBJECT *Op) 304151937Sjkim{ 305151937Sjkim ACPI_PARSE_OBJECT *Child = NULL; 306151937Sjkim 307151937Sjkim 308151937Sjkim ACPI_FUNCTION_ENTRY (); 309151937Sjkim 310151937Sjkim 311151937Sjkim switch (Op->Common.AmlOpcode) 312151937Sjkim { 313151937Sjkim case AML_SCOPE_OP: 314151937Sjkim case AML_ELSE_OP: 315151937Sjkim case AML_DEVICE_OP: 316151937Sjkim case AML_THERMAL_ZONE_OP: 317151937Sjkim case AML_INT_METHODCALL_OP: 318151937Sjkim 319151937Sjkim Child = AcpiPsGetArg (Op, 0); 320151937Sjkim break; 321151937Sjkim 322151937Sjkim case AML_BUFFER_OP: 323151937Sjkim case AML_PACKAGE_OP: 324151937Sjkim case AML_METHOD_OP: 325151937Sjkim case AML_IF_OP: 326151937Sjkim case AML_WHILE_OP: 327151937Sjkim case AML_FIELD_OP: 328151937Sjkim 329151937Sjkim Child = AcpiPsGetArg (Op, 1); 330151937Sjkim break; 331151937Sjkim 332151937Sjkim case AML_POWER_RES_OP: 333151937Sjkim case AML_INDEX_FIELD_OP: 334151937Sjkim 335151937Sjkim Child = AcpiPsGetArg (Op, 2); 336151937Sjkim break; 337151937Sjkim 338151937Sjkim case AML_PROCESSOR_OP: 339151937Sjkim case AML_BANK_FIELD_OP: 340151937Sjkim 341151937Sjkim Child = AcpiPsGetArg (Op, 3); 342151937Sjkim break; 343151937Sjkim 344250838Sjkim default: 345151937Sjkim 346151937Sjkim /* All others have no children */ 347250838Sjkim 348151937Sjkim break; 349151937Sjkim } 350151937Sjkim 351151937Sjkim return (Child); 352151937Sjkim} 353151937Sjkim#endif 354