Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
6595 serge 1
/******************************************************************************
2
 *
3
 * Module Name: dsargs - Support for execution of dynamic arguments for static
4
 *                       objects (regions, fields, buffer fields, etc.)
5
 *
6
 *****************************************************************************/
7
 
8
/*
9
 * Copyright (C) 2000 - 2015, Intel Corp.
10
 * All rights reserved.
11
 *
12
 * Redistribution and use in source and binary forms, with or without
13
 * modification, are permitted provided that the following conditions
14
 * are met:
15
 * 1. Redistributions of source code must retain the above copyright
16
 *    notice, this list of conditions, and the following disclaimer,
17
 *    without modification.
18
 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
19
 *    substantially similar to the "NO WARRANTY" disclaimer below
20
 *    ("Disclaimer") and any redistribution must be conditioned upon
21
 *    including a substantially similar Disclaimer requirement for further
22
 *    binary redistribution.
23
 * 3. Neither the names of the above-listed copyright holders nor the names
24
 *    of any contributors may be used to endorse or promote products derived
25
 *    from this software without specific prior written permission.
26
 *
27
 * Alternatively, this software may be distributed under the terms of the
28
 * GNU General Public License ("GPL") version 2 as published by the Free
29
 * Software Foundation.
30
 *
31
 * NO WARRANTY
32
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
33
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
34
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
35
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
36
 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
38
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
40
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
41
 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
42
 * POSSIBILITY OF SUCH DAMAGES.
43
 */
44
 
45
#include 
46
#include "accommon.h"
47
#include "acparser.h"
48
#include "amlcode.h"
49
#include "acdispat.h"
50
#include "acnamesp.h"
51
 
52
#define _COMPONENT          ACPI_DISPATCHER
53
ACPI_MODULE_NAME("dsargs")
54
 
55
/* Local prototypes */
56
static acpi_status
57
acpi_ds_execute_arguments(struct acpi_namespace_node *node,
58
			  struct acpi_namespace_node *scope_node,
59
			  u32 aml_length, u8 *aml_start);
60
 
61
/*******************************************************************************
62
 *
63
 * FUNCTION:    acpi_ds_execute_arguments
64
 *
65
 * PARAMETERS:  node                - Object NS node
66
 *              scope_node          - Parent NS node
67
 *              aml_length          - Length of executable AML
68
 *              aml_start           - Pointer to the AML
69
 *
70
 * RETURN:      Status.
71
 *
72
 * DESCRIPTION: Late (deferred) execution of region or field arguments
73
 *
74
 ******************************************************************************/
75
 
76
static acpi_status
77
acpi_ds_execute_arguments(struct acpi_namespace_node *node,
78
			  struct acpi_namespace_node *scope_node,
79
			  u32 aml_length, u8 *aml_start)
80
{
81
	acpi_status status;
82
	union acpi_parse_object *op;
83
	struct acpi_walk_state *walk_state;
84
 
85
	ACPI_FUNCTION_TRACE(ds_execute_arguments);
86
 
87
	/* Allocate a new parser op to be the root of the parsed tree */
88
 
89
	op = acpi_ps_alloc_op(AML_INT_EVAL_SUBTREE_OP, aml_start);
90
	if (!op) {
91
		return_ACPI_STATUS(AE_NO_MEMORY);
92
	}
93
 
94
	/* Save the Node for use in acpi_ps_parse_aml */
95
 
96
	op->common.node = scope_node;
97
 
98
	/* Create and initialize a new parser state */
99
 
100
	walk_state = acpi_ds_create_walk_state(0, NULL, NULL, NULL);
101
	if (!walk_state) {
102
		status = AE_NO_MEMORY;
103
		goto cleanup;
104
	}
105
 
106
	status = acpi_ds_init_aml_walk(walk_state, op, NULL, aml_start,
107
				       aml_length, NULL, ACPI_IMODE_LOAD_PASS1);
108
	if (ACPI_FAILURE(status)) {
109
		acpi_ds_delete_walk_state(walk_state);
110
		goto cleanup;
111
	}
112
 
113
	/* Mark this parse as a deferred opcode */
114
 
115
	walk_state->parse_flags = ACPI_PARSE_DEFERRED_OP;
116
	walk_state->deferred_node = node;
117
 
118
	/* Pass1: Parse the entire declaration */
119
 
120
	status = acpi_ps_parse_aml(walk_state);
121
	if (ACPI_FAILURE(status)) {
122
		goto cleanup;
123
	}
124
 
125
	/* Get and init the Op created above */
126
 
127
	op->common.node = node;
128
	acpi_ps_delete_parse_tree(op);
129
 
130
	/* Evaluate the deferred arguments */
131
 
132
	op = acpi_ps_alloc_op(AML_INT_EVAL_SUBTREE_OP, aml_start);
133
	if (!op) {
134
		return_ACPI_STATUS(AE_NO_MEMORY);
135
	}
136
 
137
	op->common.node = scope_node;
138
 
139
	/* Create and initialize a new parser state */
140
 
141
	walk_state = acpi_ds_create_walk_state(0, NULL, NULL, NULL);
142
	if (!walk_state) {
143
		status = AE_NO_MEMORY;
144
		goto cleanup;
145
	}
146
 
147
	/* Execute the opcode and arguments */
148
 
149
	status = acpi_ds_init_aml_walk(walk_state, op, NULL, aml_start,
150
				       aml_length, NULL, ACPI_IMODE_EXECUTE);
151
	if (ACPI_FAILURE(status)) {
152
		acpi_ds_delete_walk_state(walk_state);
153
		goto cleanup;
154
	}
155
 
156
	/* Mark this execution as a deferred opcode */
157
 
158
	walk_state->deferred_node = node;
159
	status = acpi_ps_parse_aml(walk_state);
160
 
161
cleanup:
162
	acpi_ps_delete_parse_tree(op);
163
	return_ACPI_STATUS(status);
164
}
165
 
166
/*******************************************************************************
167
 *
168
 * FUNCTION:    acpi_ds_get_buffer_field_arguments
169
 *
170
 * PARAMETERS:  obj_desc        - A valid buffer_field object
171
 *
172
 * RETURN:      Status.
173
 *
174
 * DESCRIPTION: Get buffer_field Buffer and Index. This implements the late
175
 *              evaluation of these field attributes.
176
 *
177
 ******************************************************************************/
178
 
179
acpi_status
180
acpi_ds_get_buffer_field_arguments(union acpi_operand_object *obj_desc)
181
{
182
	union acpi_operand_object *extra_desc;
183
	struct acpi_namespace_node *node;
184
	acpi_status status;
185
 
186
	ACPI_FUNCTION_TRACE_PTR(ds_get_buffer_field_arguments, obj_desc);
187
 
188
	if (obj_desc->common.flags & AOPOBJ_DATA_VALID) {
189
		return_ACPI_STATUS(AE_OK);
190
	}
191
 
192
	/* Get the AML pointer (method object) and buffer_field node */
193
 
194
	extra_desc = acpi_ns_get_secondary_object(obj_desc);
195
	node = obj_desc->buffer_field.node;
196
 
197
	ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname(ACPI_TYPE_BUFFER_FIELD,
198
						      node, NULL));
199
 
200
	ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "[%4.4s] BufferField Arg Init\n",
201
			  acpi_ut_get_node_name(node)));
202
 
203
	/* Execute the AML code for the term_arg arguments */
204
 
205
	status = acpi_ds_execute_arguments(node, node->parent,
206
					   extra_desc->extra.aml_length,
207
					   extra_desc->extra.aml_start);
208
	return_ACPI_STATUS(status);
209
}
210
 
211
/*******************************************************************************
212
 *
213
 * FUNCTION:    acpi_ds_get_bank_field_arguments
214
 *
215
 * PARAMETERS:  obj_desc        - A valid bank_field object
216
 *
217
 * RETURN:      Status.
218
 *
219
 * DESCRIPTION: Get bank_field bank_value. This implements the late
220
 *              evaluation of these field attributes.
221
 *
222
 ******************************************************************************/
223
 
224
acpi_status
225
acpi_ds_get_bank_field_arguments(union acpi_operand_object *obj_desc)
226
{
227
	union acpi_operand_object *extra_desc;
228
	struct acpi_namespace_node *node;
229
	acpi_status status;
230
 
231
	ACPI_FUNCTION_TRACE_PTR(ds_get_bank_field_arguments, obj_desc);
232
 
233
	if (obj_desc->common.flags & AOPOBJ_DATA_VALID) {
234
		return_ACPI_STATUS(AE_OK);
235
	}
236
 
237
	/* Get the AML pointer (method object) and bank_field node */
238
 
239
	extra_desc = acpi_ns_get_secondary_object(obj_desc);
240
	node = obj_desc->bank_field.node;
241
 
242
	ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname
243
			(ACPI_TYPE_LOCAL_BANK_FIELD, node, NULL));
244
 
245
	ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "[%4.4s] BankField Arg Init\n",
246
			  acpi_ut_get_node_name(node)));
247
 
248
	/* Execute the AML code for the term_arg arguments */
249
 
250
	status = acpi_ds_execute_arguments(node, node->parent,
251
					   extra_desc->extra.aml_length,
252
					   extra_desc->extra.aml_start);
253
	if (ACPI_FAILURE(status)) {
254
		return_ACPI_STATUS(status);
255
	}
256
 
257
	status = acpi_ut_add_address_range(obj_desc->region.space_id,
258
					   obj_desc->region.address,
259
					   obj_desc->region.length, node);
260
	return_ACPI_STATUS(status);
261
}
262
 
263
/*******************************************************************************
264
 *
265
 * FUNCTION:    acpi_ds_get_buffer_arguments
266
 *
267
 * PARAMETERS:  obj_desc        - A valid Buffer object
268
 *
269
 * RETURN:      Status.
270
 *
271
 * DESCRIPTION: Get Buffer length and initializer byte list. This implements
272
 *              the late evaluation of these attributes.
273
 *
274
 ******************************************************************************/
275
 
276
acpi_status acpi_ds_get_buffer_arguments(union acpi_operand_object *obj_desc)
277
{
278
	struct acpi_namespace_node *node;
279
	acpi_status status;
280
 
281
	ACPI_FUNCTION_TRACE_PTR(ds_get_buffer_arguments, obj_desc);
282
 
283
	if (obj_desc->common.flags & AOPOBJ_DATA_VALID) {
284
		return_ACPI_STATUS(AE_OK);
285
	}
286
 
287
	/* Get the Buffer node */
288
 
289
	node = obj_desc->buffer.node;
290
	if (!node) {
291
		ACPI_ERROR((AE_INFO,
292
			    "No pointer back to namespace node in buffer object %p",
293
			    obj_desc));
294
		return_ACPI_STATUS(AE_AML_INTERNAL);
295
	}
296
 
297
	ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Buffer Arg Init\n"));
298
 
299
	/* Execute the AML code for the term_arg arguments */
300
 
301
	status = acpi_ds_execute_arguments(node, node,
302
					   obj_desc->buffer.aml_length,
303
					   obj_desc->buffer.aml_start);
304
	return_ACPI_STATUS(status);
305
}
306
 
307
/*******************************************************************************
308
 *
309
 * FUNCTION:    acpi_ds_get_package_arguments
310
 *
311
 * PARAMETERS:  obj_desc        - A valid Package object
312
 *
313
 * RETURN:      Status.
314
 *
315
 * DESCRIPTION: Get Package length and initializer byte list. This implements
316
 *              the late evaluation of these attributes.
317
 *
318
 ******************************************************************************/
319
 
320
acpi_status acpi_ds_get_package_arguments(union acpi_operand_object *obj_desc)
321
{
322
	struct acpi_namespace_node *node;
323
	acpi_status status;
324
 
325
	ACPI_FUNCTION_TRACE_PTR(ds_get_package_arguments, obj_desc);
326
 
327
	if (obj_desc->common.flags & AOPOBJ_DATA_VALID) {
328
		return_ACPI_STATUS(AE_OK);
329
	}
330
 
331
	/* Get the Package node */
332
 
333
	node = obj_desc->package.node;
334
	if (!node) {
335
		ACPI_ERROR((AE_INFO,
336
			    "No pointer back to namespace node in package %p",
337
			    obj_desc));
338
		return_ACPI_STATUS(AE_AML_INTERNAL);
339
	}
340
 
341
	ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Package Arg Init\n"));
342
 
343
	/* Execute the AML code for the term_arg arguments */
344
 
345
	status = acpi_ds_execute_arguments(node, node,
346
					   obj_desc->package.aml_length,
347
					   obj_desc->package.aml_start);
348
	return_ACPI_STATUS(status);
349
}
350
 
351
/*******************************************************************************
352
 *
353
 * FUNCTION:    acpi_ds_get_region_arguments
354
 *
355
 * PARAMETERS:  obj_desc        - A valid region object
356
 *
357
 * RETURN:      Status.
358
 *
359
 * DESCRIPTION: Get region address and length. This implements the late
360
 *              evaluation of these region attributes.
361
 *
362
 ******************************************************************************/
363
 
364
acpi_status acpi_ds_get_region_arguments(union acpi_operand_object *obj_desc)
365
{
366
	struct acpi_namespace_node *node;
367
	acpi_status status;
368
	union acpi_operand_object *extra_desc;
369
 
370
	ACPI_FUNCTION_TRACE_PTR(ds_get_region_arguments, obj_desc);
371
 
372
	if (obj_desc->region.flags & AOPOBJ_DATA_VALID) {
373
		return_ACPI_STATUS(AE_OK);
374
	}
375
 
376
	extra_desc = acpi_ns_get_secondary_object(obj_desc);
377
	if (!extra_desc) {
378
		return_ACPI_STATUS(AE_NOT_EXIST);
379
	}
380
 
381
	/* Get the Region node */
382
 
383
	node = obj_desc->region.node;
384
 
385
	ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname
386
			(ACPI_TYPE_REGION, node, NULL));
387
 
388
	ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "[%4.4s] OpRegion Arg Init at AML %p\n",
389
			  acpi_ut_get_node_name(node),
390
			  extra_desc->extra.aml_start));
391
 
392
	/* Execute the argument AML */
393
 
394
	status = acpi_ds_execute_arguments(node, extra_desc->extra.scope_node,
395
					   extra_desc->extra.aml_length,
396
					   extra_desc->extra.aml_start);
397
	if (ACPI_FAILURE(status)) {
398
		return_ACPI_STATUS(status);
399
	}
400
 
401
	status = acpi_ut_add_address_range(obj_desc->region.space_id,
402
					   obj_desc->region.address,
403
					   obj_desc->region.length, node);
404
	return_ACPI_STATUS(status);
405
}