Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
0002 /******************************************************************************
0003  *
0004  * Module Name: pstree - Parser op tree manipulation/traversal/search
0005  *
0006  * Copyright (C) 2000 - 2022, Intel Corp.
0007  *
0008  *****************************************************************************/
0009 
0010 #include <acpi/acpi.h>
0011 #include "accommon.h"
0012 #include "acparser.h"
0013 #include "amlcode.h"
0014 #include "acconvert.h"
0015 
0016 #define _COMPONENT          ACPI_PARSER
0017 ACPI_MODULE_NAME("pstree")
0018 
0019 /* Local prototypes */
0020 #ifdef ACPI_OBSOLETE_FUNCTIONS
0021 union acpi_parse_object *acpi_ps_get_child(union acpi_parse_object *op);
0022 #endif
0023 
0024 /*******************************************************************************
0025  *
0026  * FUNCTION:    acpi_ps_get_arg
0027  *
0028  * PARAMETERS:  op              - Get an argument for this op
0029  *              argn            - Nth argument to get
0030  *
0031  * RETURN:      The argument (as an Op object). NULL if argument does not exist
0032  *
0033  * DESCRIPTION: Get the specified op's argument.
0034  *
0035  ******************************************************************************/
0036 
0037 union acpi_parse_object *acpi_ps_get_arg(union acpi_parse_object *op, u32 argn)
0038 {
0039     union acpi_parse_object *arg = NULL;
0040     const struct acpi_opcode_info *op_info;
0041 
0042     ACPI_FUNCTION_ENTRY();
0043 
0044 /*
0045     if (Op->Common.aml_opcode == AML_INT_CONNECTION_OP)
0046     {
0047         return (Op->Common.Value.Arg);
0048     }
0049 */
0050     /* Get the info structure for this opcode */
0051 
0052     op_info = acpi_ps_get_opcode_info(op->common.aml_opcode);
0053     if (op_info->class == AML_CLASS_UNKNOWN) {
0054 
0055         /* Invalid opcode or ASCII character */
0056 
0057         return (NULL);
0058     }
0059 
0060     /* Check if this opcode requires argument sub-objects */
0061 
0062     if (!(op_info->flags & AML_HAS_ARGS)) {
0063 
0064         /* Has no linked argument objects */
0065 
0066         return (NULL);
0067     }
0068 
0069     /* Get the requested argument object */
0070 
0071     arg = op->common.value.arg;
0072     while (arg && argn) {
0073         argn--;
0074         arg = arg->common.next;
0075     }
0076 
0077     return (arg);
0078 }
0079 
0080 /*******************************************************************************
0081  *
0082  * FUNCTION:    acpi_ps_append_arg
0083  *
0084  * PARAMETERS:  op              - Append an argument to this Op.
0085  *              arg             - Argument Op to append
0086  *
0087  * RETURN:      None.
0088  *
0089  * DESCRIPTION: Append an argument to an op's argument list (a NULL arg is OK)
0090  *
0091  ******************************************************************************/
0092 
0093 void
0094 acpi_ps_append_arg(union acpi_parse_object *op, union acpi_parse_object *arg)
0095 {
0096     union acpi_parse_object *prev_arg;
0097     const struct acpi_opcode_info *op_info;
0098 
0099     ACPI_FUNCTION_TRACE(ps_append_arg);
0100 
0101     if (!op) {
0102         return_VOID;
0103     }
0104 
0105     /* Get the info structure for this opcode */
0106 
0107     op_info = acpi_ps_get_opcode_info(op->common.aml_opcode);
0108     if (op_info->class == AML_CLASS_UNKNOWN) {
0109 
0110         /* Invalid opcode */
0111 
0112         ACPI_ERROR((AE_INFO, "Invalid AML Opcode: 0x%2.2X",
0113                 op->common.aml_opcode));
0114         return_VOID;
0115     }
0116 
0117     /* Check if this opcode requires argument sub-objects */
0118 
0119     if (!(op_info->flags & AML_HAS_ARGS)) {
0120 
0121         /* Has no linked argument objects */
0122 
0123         return_VOID;
0124     }
0125 
0126     /* Append the argument to the linked argument list */
0127 
0128     if (op->common.value.arg) {
0129 
0130         /* Append to existing argument list */
0131 
0132         prev_arg = op->common.value.arg;
0133         while (prev_arg->common.next) {
0134             prev_arg = prev_arg->common.next;
0135         }
0136         prev_arg->common.next = arg;
0137     } else {
0138         /* No argument list, this will be the first argument */
0139 
0140         op->common.value.arg = arg;
0141     }
0142 
0143     /* Set the parent in this arg and any args linked after it */
0144 
0145     while (arg) {
0146         arg->common.parent = op;
0147         arg = arg->common.next;
0148 
0149         op->common.arg_list_length++;
0150     }
0151 
0152     return_VOID;
0153 }
0154 
0155 /*******************************************************************************
0156  *
0157  * FUNCTION:    acpi_ps_get_depth_next
0158  *
0159  * PARAMETERS:  origin          - Root of subtree to search
0160  *              op              - Last (previous) Op that was found
0161  *
0162  * RETURN:      Next Op found in the search.
0163  *
0164  * DESCRIPTION: Get next op in tree (walking the tree in depth-first order)
0165  *              Return NULL when reaching "origin" or when walking up from root
0166  *
0167  ******************************************************************************/
0168 
0169 union acpi_parse_object *acpi_ps_get_depth_next(union acpi_parse_object *origin,
0170                         union acpi_parse_object *op)
0171 {
0172     union acpi_parse_object *next = NULL;
0173     union acpi_parse_object *parent;
0174     union acpi_parse_object *arg;
0175 
0176     ACPI_FUNCTION_ENTRY();
0177 
0178     if (!op) {
0179         return (NULL);
0180     }
0181 
0182     /* Look for an argument or child */
0183 
0184     next = acpi_ps_get_arg(op, 0);
0185     if (next) {
0186         ASL_CV_LABEL_FILENODE(next);
0187         return (next);
0188     }
0189 
0190     /* Look for a sibling */
0191 
0192     next = op->common.next;
0193     if (next) {
0194         ASL_CV_LABEL_FILENODE(next);
0195         return (next);
0196     }
0197 
0198     /* Look for a sibling of parent */
0199 
0200     parent = op->common.parent;
0201 
0202     while (parent) {
0203         arg = acpi_ps_get_arg(parent, 0);
0204         while (arg && (arg != origin) && (arg != op)) {
0205 
0206             ASL_CV_LABEL_FILENODE(arg);
0207             arg = arg->common.next;
0208         }
0209 
0210         if (arg == origin) {
0211 
0212             /* Reached parent of origin, end search */
0213 
0214             return (NULL);
0215         }
0216 
0217         if (parent->common.next) {
0218 
0219             /* Found sibling of parent */
0220 
0221             ASL_CV_LABEL_FILENODE(parent->common.next);
0222             return (parent->common.next);
0223         }
0224 
0225         op = parent;
0226         parent = parent->common.parent;
0227     }
0228 
0229     ASL_CV_LABEL_FILENODE(next);
0230     return (next);
0231 }
0232 
0233 #ifdef ACPI_OBSOLETE_FUNCTIONS
0234 /*******************************************************************************
0235  *
0236  * FUNCTION:    acpi_ps_get_child
0237  *
0238  * PARAMETERS:  op              - Get the child of this Op
0239  *
0240  * RETURN:      Child Op, Null if none is found.
0241  *
0242  * DESCRIPTION: Get op's children or NULL if none
0243  *
0244  ******************************************************************************/
0245 
0246 union acpi_parse_object *acpi_ps_get_child(union acpi_parse_object *op)
0247 {
0248     union acpi_parse_object *child = NULL;
0249 
0250     ACPI_FUNCTION_ENTRY();
0251 
0252     switch (op->common.aml_opcode) {
0253     case AML_SCOPE_OP:
0254     case AML_ELSE_OP:
0255     case AML_DEVICE_OP:
0256     case AML_THERMAL_ZONE_OP:
0257     case AML_INT_METHODCALL_OP:
0258 
0259         child = acpi_ps_get_arg(op, 0);
0260         break;
0261 
0262     case AML_BUFFER_OP:
0263     case AML_PACKAGE_OP:
0264     case AML_VARIABLE_PACKAGE_OP:
0265     case AML_METHOD_OP:
0266     case AML_IF_OP:
0267     case AML_WHILE_OP:
0268     case AML_FIELD_OP:
0269 
0270         child = acpi_ps_get_arg(op, 1);
0271         break;
0272 
0273     case AML_POWER_RESOURCE_OP:
0274     case AML_INDEX_FIELD_OP:
0275 
0276         child = acpi_ps_get_arg(op, 2);
0277         break;
0278 
0279     case AML_PROCESSOR_OP:
0280     case AML_BANK_FIELD_OP:
0281 
0282         child = acpi_ps_get_arg(op, 3);
0283         break;
0284 
0285     default:
0286 
0287         /* All others have no children */
0288 
0289         break;
0290     }
0291 
0292     return (child);
0293 }
0294 #endif