pstree.c 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294
  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 - 2018, Intel Corp.
  7. *
  8. *****************************************************************************/
  9. #include <acpi/acpi.h>
  10. #include "accommon.h"
  11. #include "acparser.h"
  12. #include "amlcode.h"
  13. #include "acconvert.h"
  14. #define _COMPONENT ACPI_PARSER
  15. ACPI_MODULE_NAME("pstree")
  16. /* Local prototypes */
  17. #ifdef ACPI_OBSOLETE_FUNCTIONS
  18. union acpi_parse_object *acpi_ps_get_child(union acpi_parse_object *op);
  19. #endif
  20. /*******************************************************************************
  21. *
  22. * FUNCTION: acpi_ps_get_arg
  23. *
  24. * PARAMETERS: op - Get an argument for this op
  25. * argn - Nth argument to get
  26. *
  27. * RETURN: The argument (as an Op object). NULL if argument does not exist
  28. *
  29. * DESCRIPTION: Get the specified op's argument.
  30. *
  31. ******************************************************************************/
  32. union acpi_parse_object *acpi_ps_get_arg(union acpi_parse_object *op, u32 argn)
  33. {
  34. union acpi_parse_object *arg = NULL;
  35. const struct acpi_opcode_info *op_info;
  36. ACPI_FUNCTION_ENTRY();
  37. /*
  38. if (Op->Common.aml_opcode == AML_INT_CONNECTION_OP)
  39. {
  40. return (Op->Common.Value.Arg);
  41. }
  42. */
  43. /* Get the info structure for this opcode */
  44. op_info = acpi_ps_get_opcode_info(op->common.aml_opcode);
  45. if (op_info->class == AML_CLASS_UNKNOWN) {
  46. /* Invalid opcode or ASCII character */
  47. return (NULL);
  48. }
  49. /* Check if this opcode requires argument sub-objects */
  50. if (!(op_info->flags & AML_HAS_ARGS)) {
  51. /* Has no linked argument objects */
  52. return (NULL);
  53. }
  54. /* Get the requested argument object */
  55. arg = op->common.value.arg;
  56. while (arg && argn) {
  57. argn--;
  58. arg = arg->common.next;
  59. }
  60. return (arg);
  61. }
  62. /*******************************************************************************
  63. *
  64. * FUNCTION: acpi_ps_append_arg
  65. *
  66. * PARAMETERS: op - Append an argument to this Op.
  67. * arg - Argument Op to append
  68. *
  69. * RETURN: None.
  70. *
  71. * DESCRIPTION: Append an argument to an op's argument list (a NULL arg is OK)
  72. *
  73. ******************************************************************************/
  74. void
  75. acpi_ps_append_arg(union acpi_parse_object *op, union acpi_parse_object *arg)
  76. {
  77. union acpi_parse_object *prev_arg;
  78. const struct acpi_opcode_info *op_info;
  79. ACPI_FUNCTION_TRACE(ps_append_arg);
  80. if (!op) {
  81. return_VOID;
  82. }
  83. /* Get the info structure for this opcode */
  84. op_info = acpi_ps_get_opcode_info(op->common.aml_opcode);
  85. if (op_info->class == AML_CLASS_UNKNOWN) {
  86. /* Invalid opcode */
  87. ACPI_ERROR((AE_INFO, "Invalid AML Opcode: 0x%2.2X",
  88. op->common.aml_opcode));
  89. return_VOID;
  90. }
  91. /* Check if this opcode requires argument sub-objects */
  92. if (!(op_info->flags & AML_HAS_ARGS)) {
  93. /* Has no linked argument objects */
  94. return_VOID;
  95. }
  96. /* Append the argument to the linked argument list */
  97. if (op->common.value.arg) {
  98. /* Append to existing argument list */
  99. prev_arg = op->common.value.arg;
  100. while (prev_arg->common.next) {
  101. prev_arg = prev_arg->common.next;
  102. }
  103. prev_arg->common.next = arg;
  104. } else {
  105. /* No argument list, this will be the first argument */
  106. op->common.value.arg = arg;
  107. }
  108. /* Set the parent in this arg and any args linked after it */
  109. while (arg) {
  110. arg->common.parent = op;
  111. arg = arg->common.next;
  112. op->common.arg_list_length++;
  113. }
  114. return_VOID;
  115. }
  116. /*******************************************************************************
  117. *
  118. * FUNCTION: acpi_ps_get_depth_next
  119. *
  120. * PARAMETERS: origin - Root of subtree to search
  121. * op - Last (previous) Op that was found
  122. *
  123. * RETURN: Next Op found in the search.
  124. *
  125. * DESCRIPTION: Get next op in tree (walking the tree in depth-first order)
  126. * Return NULL when reaching "origin" or when walking up from root
  127. *
  128. ******************************************************************************/
  129. union acpi_parse_object *acpi_ps_get_depth_next(union acpi_parse_object *origin,
  130. union acpi_parse_object *op)
  131. {
  132. union acpi_parse_object *next = NULL;
  133. union acpi_parse_object *parent;
  134. union acpi_parse_object *arg;
  135. ACPI_FUNCTION_ENTRY();
  136. if (!op) {
  137. return (NULL);
  138. }
  139. /* Look for an argument or child */
  140. next = acpi_ps_get_arg(op, 0);
  141. if (next) {
  142. ASL_CV_LABEL_FILENODE(next);
  143. return (next);
  144. }
  145. /* Look for a sibling */
  146. next = op->common.next;
  147. if (next) {
  148. ASL_CV_LABEL_FILENODE(next);
  149. return (next);
  150. }
  151. /* Look for a sibling of parent */
  152. parent = op->common.parent;
  153. while (parent) {
  154. arg = acpi_ps_get_arg(parent, 0);
  155. while (arg && (arg != origin) && (arg != op)) {
  156. ASL_CV_LABEL_FILENODE(arg);
  157. arg = arg->common.next;
  158. }
  159. if (arg == origin) {
  160. /* Reached parent of origin, end search */
  161. return (NULL);
  162. }
  163. if (parent->common.next) {
  164. /* Found sibling of parent */
  165. ASL_CV_LABEL_FILENODE(parent->common.next);
  166. return (parent->common.next);
  167. }
  168. op = parent;
  169. parent = parent->common.parent;
  170. }
  171. ASL_CV_LABEL_FILENODE(next);
  172. return (next);
  173. }
  174. #ifdef ACPI_OBSOLETE_FUNCTIONS
  175. /*******************************************************************************
  176. *
  177. * FUNCTION: acpi_ps_get_child
  178. *
  179. * PARAMETERS: op - Get the child of this Op
  180. *
  181. * RETURN: Child Op, Null if none is found.
  182. *
  183. * DESCRIPTION: Get op's children or NULL if none
  184. *
  185. ******************************************************************************/
  186. union acpi_parse_object *acpi_ps_get_child(union acpi_parse_object *op)
  187. {
  188. union acpi_parse_object *child = NULL;
  189. ACPI_FUNCTION_ENTRY();
  190. switch (op->common.aml_opcode) {
  191. case AML_SCOPE_OP:
  192. case AML_ELSE_OP:
  193. case AML_DEVICE_OP:
  194. case AML_THERMAL_ZONE_OP:
  195. case AML_INT_METHODCALL_OP:
  196. child = acpi_ps_get_arg(op, 0);
  197. break;
  198. case AML_BUFFER_OP:
  199. case AML_PACKAGE_OP:
  200. case AML_VARIABLE_PACKAGE_OP:
  201. case AML_METHOD_OP:
  202. case AML_IF_OP:
  203. case AML_WHILE_OP:
  204. case AML_FIELD_OP:
  205. child = acpi_ps_get_arg(op, 1);
  206. break;
  207. case AML_POWER_RESOURCE_OP:
  208. case AML_INDEX_FIELD_OP:
  209. child = acpi_ps_get_arg(op, 2);
  210. break;
  211. case AML_PROCESSOR_OP:
  212. case AML_BANK_FIELD_OP:
  213. child = acpi_ps_get_arg(op, 3);
  214. break;
  215. default:
  216. /* All others have no children */
  217. break;
  218. }
  219. return (child);
  220. }
  221. #endif