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