Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

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