Branch data Line data Source code
1 : : // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 2 : : /****************************************************************************** 3 : : * 4 : : * Module Name: pstree - Parser op tree manipulation/traversal/search 5 : : * 6 : : * Copyright (C) 2000 - 2020, Intel Corp. 7 : : * 8 : : *****************************************************************************/ 9 : : 10 : : #include <acpi/acpi.h> 11 : : #include "accommon.h" 12 : : #include "acparser.h" 13 : : #include "amlcode.h" 14 : : #include "acconvert.h" 15 : : 16 : : #define _COMPONENT ACPI_PARSER 17 : : ACPI_MODULE_NAME("pstree") 18 : : 19 : : /* Local prototypes */ 20 : : #ifdef ACPI_OBSOLETE_FUNCTIONS 21 : : union acpi_parse_object *acpi_ps_get_child(union acpi_parse_object *op); 22 : : #endif 23 : : 24 : : /******************************************************************************* 25 : : * 26 : : * FUNCTION: acpi_ps_get_arg 27 : : * 28 : : * PARAMETERS: op - Get an argument for this op 29 : : * argn - Nth argument to get 30 : : * 31 : : * RETURN: The argument (as an Op object). NULL if argument does not exist 32 : : * 33 : : * DESCRIPTION: Get the specified op's argument. 34 : : * 35 : : ******************************************************************************/ 36 : : 37 : 306670 : union acpi_parse_object *acpi_ps_get_arg(union acpi_parse_object *op, u32 argn) 38 : : { 39 : 306670 : union acpi_parse_object *arg = NULL; 40 : 306670 : const struct acpi_opcode_info *op_info; 41 : : 42 : 306670 : ACPI_FUNCTION_ENTRY(); 43 : : 44 : : /* 45 : : if (Op->Common.aml_opcode == AML_INT_CONNECTION_OP) 46 : : { 47 : : return (Op->Common.Value.Arg); 48 : : } 49 : : */ 50 : : /* Get the info structure for this opcode */ 51 : : 52 : 306670 : op_info = acpi_ps_get_opcode_info(op->common.aml_opcode); 53 [ + - ]: 306670 : if (op_info->class == AML_CLASS_UNKNOWN) { 54 : : 55 : : /* Invalid opcode or ASCII character */ 56 : : 57 : : return (NULL); 58 : : } 59 : : 60 : : /* Check if this opcode requires argument sub-objects */ 61 : : 62 [ + + ]: 306670 : if (!(op_info->flags & AML_HAS_ARGS)) { 63 : : 64 : : /* Has no linked argument objects */ 65 : : 66 : : return (NULL); 67 : : } 68 : : 69 : : /* Get the requested argument object */ 70 : : 71 : 140023 : arg = op->common.value.arg; 72 [ + + ]: 140517 : while (arg && argn) { 73 : 494 : argn--; 74 : 494 : arg = arg->common.next; 75 : : } 76 : : 77 : : return (arg); 78 : : } 79 : : 80 : : /******************************************************************************* 81 : : * 82 : : * FUNCTION: acpi_ps_append_arg 83 : : * 84 : : * PARAMETERS: op - Append an argument to this Op. 85 : : * arg - Argument Op to append 86 : : * 87 : : * RETURN: None. 88 : : * 89 : : * DESCRIPTION: Append an argument to an op's argument list (a NULL arg is OK) 90 : : * 91 : : ******************************************************************************/ 92 : : 93 : : void 94 : 272298 : acpi_ps_append_arg(union acpi_parse_object *op, union acpi_parse_object *arg) 95 : : { 96 : 272298 : union acpi_parse_object *prev_arg; 97 : 272298 : const struct acpi_opcode_info *op_info; 98 : : 99 : 272298 : ACPI_FUNCTION_TRACE(ps_append_arg); 100 : : 101 [ + + ]: 272298 : if (!op) { 102 : : return_VOID; 103 : : } 104 : : 105 : : /* Get the info structure for this opcode */ 106 : : 107 : 271453 : op_info = acpi_ps_get_opcode_info(op->common.aml_opcode); 108 [ - + ]: 271453 : if (op_info->class == AML_CLASS_UNKNOWN) { 109 : : 110 : : /* Invalid opcode */ 111 : : 112 : 0 : ACPI_ERROR((AE_INFO, "Invalid AML Opcode: 0x%2.2X", 113 : : op->common.aml_opcode)); 114 : 0 : return_VOID; 115 : : } 116 : : 117 : : /* Check if this opcode requires argument sub-objects */ 118 : : 119 [ + - ]: 271453 : if (!(op_info->flags & AML_HAS_ARGS)) { 120 : : 121 : : /* Has no linked argument objects */ 122 : : 123 : : return_VOID; 124 : : } 125 : : 126 : : /* Append the argument to the linked argument list */ 127 : : 128 [ + + ]: 271453 : if (op->common.value.arg) { 129 : : 130 : : /* Append to existing argument list */ 131 : : 132 : : prev_arg = op->common.value.arg; 133 [ + + ]: 171509 : while (prev_arg->common.next) { 134 : : prev_arg = prev_arg->common.next; 135 : : } 136 : 117702 : prev_arg->common.next = arg; 137 : : } else { 138 : : /* No argument list, this will be the first argument */ 139 : : 140 : 153751 : op->common.value.arg = arg; 141 : : } 142 : : 143 : : /* Set the parent in this arg and any args linked after it */ 144 : : 145 [ + + ]: 537498 : while (arg) { 146 : 266045 : arg->common.parent = op; 147 : 266045 : arg = arg->common.next; 148 : : 149 : 266045 : op->common.arg_list_length++; 150 : : } 151 : : 152 : : return_VOID; 153 : : } 154 : : 155 : : /******************************************************************************* 156 : : * 157 : : * FUNCTION: acpi_ps_get_depth_next 158 : : * 159 : : * PARAMETERS: origin - Root of subtree to search 160 : : * op - Last (previous) Op that was found 161 : : * 162 : : * RETURN: Next Op found in the search. 163 : : * 164 : : * DESCRIPTION: Get next op in tree (walking the tree in depth-first order) 165 : : * Return NULL when reaching "origin" or when walking up from root 166 : : * 167 : : ******************************************************************************/ 168 : : 169 : 0 : union acpi_parse_object *acpi_ps_get_depth_next(union acpi_parse_object *origin, 170 : : union acpi_parse_object *op) 171 : : { 172 : 0 : union acpi_parse_object *next = NULL; 173 : 0 : union acpi_parse_object *parent; 174 : 0 : union acpi_parse_object *arg; 175 : : 176 : 0 : ACPI_FUNCTION_ENTRY(); 177 : : 178 [ # # ]: 0 : if (!op) { 179 : : return (NULL); 180 : : } 181 : : 182 : : /* Look for an argument or child */ 183 : : 184 : 0 : next = acpi_ps_get_arg(op, 0); 185 [ # # ]: 0 : if (next) { 186 : : ASL_CV_LABEL_FILENODE(next); 187 : : return (next); 188 : : } 189 : : 190 : : /* Look for a sibling */ 191 : : 192 : 0 : next = op->common.next; 193 [ # # ]: 0 : if (next) { 194 : : ASL_CV_LABEL_FILENODE(next); 195 : : return (next); 196 : : } 197 : : 198 : : /* Look for a sibling of parent */ 199 : : 200 : 0 : parent = op->common.parent; 201 : : 202 [ # # ]: 0 : while (parent) { 203 : 0 : arg = acpi_ps_get_arg(parent, 0); 204 [ # # # # ]: 0 : while (arg && (arg != origin) && (arg != op)) { 205 : : 206 : 0 : ASL_CV_LABEL_FILENODE(arg); 207 : 0 : arg = arg->common.next; 208 : : } 209 : : 210 [ # # ]: 0 : if (arg == origin) { 211 : : 212 : : /* Reached parent of origin, end search */ 213 : : 214 : : return (NULL); 215 : : } 216 : : 217 [ # # ]: 0 : if (parent->common.next) { 218 : : 219 : : /* Found sibling of parent */ 220 : : 221 : 0 : ASL_CV_LABEL_FILENODE(parent->common.next); 222 : 0 : return (parent->common.next); 223 : : } 224 : : 225 : 0 : op = parent; 226 : 0 : parent = parent->common.parent; 227 : : } 228 : : 229 : : ASL_CV_LABEL_FILENODE(next); 230 : : return (next); 231 : : } 232 : : 233 : : #ifdef ACPI_OBSOLETE_FUNCTIONS 234 : : /******************************************************************************* 235 : : * 236 : : * FUNCTION: acpi_ps_get_child 237 : : * 238 : : * PARAMETERS: op - Get the child of this Op 239 : : * 240 : : * RETURN: Child Op, Null if none is found. 241 : : * 242 : : * DESCRIPTION: Get op's children or NULL if none 243 : : * 244 : : ******************************************************************************/ 245 : : 246 : : union acpi_parse_object *acpi_ps_get_child(union acpi_parse_object *op) 247 : : { 248 : : union acpi_parse_object *child = NULL; 249 : : 250 : : ACPI_FUNCTION_ENTRY(); 251 : : 252 : : switch (op->common.aml_opcode) { 253 : : case AML_SCOPE_OP: 254 : : case AML_ELSE_OP: 255 : : case AML_DEVICE_OP: 256 : : case AML_THERMAL_ZONE_OP: 257 : : case AML_INT_METHODCALL_OP: 258 : : 259 : : child = acpi_ps_get_arg(op, 0); 260 : : break; 261 : : 262 : : case AML_BUFFER_OP: 263 : : case AML_PACKAGE_OP: 264 : : case AML_VARIABLE_PACKAGE_OP: 265 : : case AML_METHOD_OP: 266 : : case AML_IF_OP: 267 : : case AML_WHILE_OP: 268 : : case AML_FIELD_OP: 269 : : 270 : : child = acpi_ps_get_arg(op, 1); 271 : : break; 272 : : 273 : : case AML_POWER_RESOURCE_OP: 274 : : case AML_INDEX_FIELD_OP: 275 : : 276 : : child = acpi_ps_get_arg(op, 2); 277 : : break; 278 : : 279 : : case AML_PROCESSOR_OP: 280 : : case AML_BANK_FIELD_OP: 281 : : 282 : : child = acpi_ps_get_arg(op, 3); 283 : : break; 284 : : 285 : : default: 286 : : 287 : : /* All others have no children */ 288 : : 289 : : break; 290 : : } 291 : : 292 : : return (child); 293 : : } 294 : : #endif