cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

pstree.c (6456B)


      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 - 2022, 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
     17ACPI_MODULE_NAME("pstree")
     18
     19/* Local prototypes */
     20#ifdef ACPI_OBSOLETE_FUNCTIONS
     21union 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
     37union acpi_parse_object *acpi_ps_get_arg(union acpi_parse_object *op, u32 argn)
     38{
     39	union acpi_parse_object *arg = NULL;
     40	const struct acpi_opcode_info *op_info;
     41
     42	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	op_info = acpi_ps_get_opcode_info(op->common.aml_opcode);
     53	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	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	arg = op->common.value.arg;
     72	while (arg && argn) {
     73		argn--;
     74		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
     93void
     94acpi_ps_append_arg(union acpi_parse_object *op, union acpi_parse_object *arg)
     95{
     96	union acpi_parse_object *prev_arg;
     97	const struct acpi_opcode_info *op_info;
     98
     99	ACPI_FUNCTION_TRACE(ps_append_arg);
    100
    101	if (!op) {
    102		return_VOID;
    103	}
    104
    105	/* Get the info structure for this opcode */
    106
    107	op_info = acpi_ps_get_opcode_info(op->common.aml_opcode);
    108	if (op_info->class == AML_CLASS_UNKNOWN) {
    109
    110		/* Invalid opcode */
    111
    112		ACPI_ERROR((AE_INFO, "Invalid AML Opcode: 0x%2.2X",
    113			    op->common.aml_opcode));
    114		return_VOID;
    115	}
    116
    117	/* Check if this opcode requires argument sub-objects */
    118
    119	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	if (op->common.value.arg) {
    129
    130		/* Append to existing argument list */
    131
    132		prev_arg = op->common.value.arg;
    133		while (prev_arg->common.next) {
    134			prev_arg = prev_arg->common.next;
    135		}
    136		prev_arg->common.next = arg;
    137	} else {
    138		/* No argument list, this will be the first argument */
    139
    140		op->common.value.arg = arg;
    141	}
    142
    143	/* Set the parent in this arg and any args linked after it */
    144
    145	while (arg) {
    146		arg->common.parent = op;
    147		arg = arg->common.next;
    148
    149		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
    169union acpi_parse_object *acpi_ps_get_depth_next(union acpi_parse_object *origin,
    170						union acpi_parse_object *op)
    171{
    172	union acpi_parse_object *next = NULL;
    173	union acpi_parse_object *parent;
    174	union acpi_parse_object *arg;
    175
    176	ACPI_FUNCTION_ENTRY();
    177
    178	if (!op) {
    179		return (NULL);
    180	}
    181
    182	/* Look for an argument or child */
    183
    184	next = acpi_ps_get_arg(op, 0);
    185	if (next) {
    186		ASL_CV_LABEL_FILENODE(next);
    187		return (next);
    188	}
    189
    190	/* Look for a sibling */
    191
    192	next = op->common.next;
    193	if (next) {
    194		ASL_CV_LABEL_FILENODE(next);
    195		return (next);
    196	}
    197
    198	/* Look for a sibling of parent */
    199
    200	parent = op->common.parent;
    201
    202	while (parent) {
    203		arg = acpi_ps_get_arg(parent, 0);
    204		while (arg && (arg != origin) && (arg != op)) {
    205
    206			ASL_CV_LABEL_FILENODE(arg);
    207			arg = arg->common.next;
    208		}
    209
    210		if (arg == origin) {
    211
    212			/* Reached parent of origin, end search */
    213
    214			return (NULL);
    215		}
    216
    217		if (parent->common.next) {
    218
    219			/* Found sibling of parent */
    220
    221			ASL_CV_LABEL_FILENODE(parent->common.next);
    222			return (parent->common.next);
    223		}
    224
    225		op = parent;
    226		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
    246union 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