aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/dispatcher
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi/dispatcher')
-rw-r--r--drivers/acpi/dispatcher/Makefile9
-rw-r--r--drivers/acpi/dispatcher/dsfield.c601
-rw-r--r--drivers/acpi/dispatcher/dsinit.c235
-rw-r--r--drivers/acpi/dispatcher/dsmethod.c597
-rw-r--r--drivers/acpi/dispatcher/dsmthdat.c715
-rw-r--r--drivers/acpi/dispatcher/dsobject.c618
-rw-r--r--drivers/acpi/dispatcher/dsopcode.c1151
-rw-r--r--drivers/acpi/dispatcher/dsutils.c744
-rw-r--r--drivers/acpi/dispatcher/dswexec.c751
-rw-r--r--drivers/acpi/dispatcher/dswload.c976
-rw-r--r--drivers/acpi/dispatcher/dswscope.c229
-rw-r--r--drivers/acpi/dispatcher/dswstate.c1100
12 files changed, 7726 insertions, 0 deletions
diff --git a/drivers/acpi/dispatcher/Makefile b/drivers/acpi/dispatcher/Makefile
new file mode 100644
index 000000000000..eb7e602a83cd
--- /dev/null
+++ b/drivers/acpi/dispatcher/Makefile
@@ -0,0 +1,9 @@
1#
2# Makefile for all Linux ACPI interpreter subdirectories
3#
4
5obj-y := dsfield.o dsmthdat.o dsopcode.o dswexec.o dswscope.o \
6 dsmethod.o dsobject.o dsutils.o dswload.o dswstate.o \
7 dsinit.o
8
9EXTRA_CFLAGS += $(ACPI_CFLAGS)
diff --git a/drivers/acpi/dispatcher/dsfield.c b/drivers/acpi/dispatcher/dsfield.c
new file mode 100644
index 000000000000..2779211be756
--- /dev/null
+++ b/drivers/acpi/dispatcher/dsfield.c
@@ -0,0 +1,601 @@
1/******************************************************************************
2 *
3 * Module Name: dsfield - Dispatcher field routines
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2005, R. Byron Moore
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
45#include <acpi/acpi.h>
46#include <acpi/amlcode.h>
47#include <acpi/acdispat.h>
48#include <acpi/acinterp.h>
49#include <acpi/acnamesp.h>
50#include <acpi/acparser.h>
51
52
53#define _COMPONENT ACPI_DISPATCHER
54 ACPI_MODULE_NAME ("dsfield")
55
56
57/*******************************************************************************
58 *
59 * FUNCTION: acpi_ds_create_buffer_field
60 *
61 * PARAMETERS: Opcode - The opcode to be executed
62 * Operands - List of operands for the opcode
63 * walk_state - Current state
64 *
65 * RETURN: Status
66 *
67 * DESCRIPTION: Execute the create_field operators:
68 * create_bit_field_op,
69 * create_byte_field_op,
70 * create_word_field_op,
71 * create_dword_field_op,
72 * create_qword_field_op,
73 * create_field_op (all of which define fields in buffers)
74 *
75 ******************************************************************************/
76
77acpi_status
78acpi_ds_create_buffer_field (
79 union acpi_parse_object *op,
80 struct acpi_walk_state *walk_state)
81{
82 union acpi_parse_object *arg;
83 struct acpi_namespace_node *node;
84 acpi_status status;
85 union acpi_operand_object *obj_desc;
86 union acpi_operand_object *second_desc = NULL;
87 u32 flags;
88
89
90 ACPI_FUNCTION_TRACE ("ds_create_buffer_field");
91
92
93 /* Get the name_string argument */
94
95 if (op->common.aml_opcode == AML_CREATE_FIELD_OP) {
96 arg = acpi_ps_get_arg (op, 3);
97 }
98 else {
99 /* Create Bit/Byte/Word/Dword field */
100
101 arg = acpi_ps_get_arg (op, 2);
102 }
103
104 if (!arg) {
105 return_ACPI_STATUS (AE_AML_NO_OPERAND);
106 }
107
108 if (walk_state->deferred_node) {
109 node = walk_state->deferred_node;
110 status = AE_OK;
111 }
112 else {
113 /*
114 * During the load phase, we want to enter the name of the field into
115 * the namespace. During the execute phase (when we evaluate the size
116 * operand), we want to lookup the name
117 */
118 if (walk_state->parse_flags & ACPI_PARSE_EXECUTE) {
119 flags = ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE;
120 }
121 else {
122 flags = ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE | ACPI_NS_ERROR_IF_FOUND;
123 }
124
125 /*
126 * Enter the name_string into the namespace
127 */
128 status = acpi_ns_lookup (walk_state->scope_info, arg->common.value.string,
129 ACPI_TYPE_ANY, ACPI_IMODE_LOAD_PASS1,
130 flags, walk_state, &(node));
131 if (ACPI_FAILURE (status)) {
132 ACPI_REPORT_NSERROR (arg->common.value.string, status);
133 return_ACPI_STATUS (status);
134 }
135 }
136
137 /* We could put the returned object (Node) on the object stack for later, but
138 * for now, we will put it in the "op" object that the parser uses, so we
139 * can get it again at the end of this scope
140 */
141 op->common.node = node;
142
143 /*
144 * If there is no object attached to the node, this node was just created and
145 * we need to create the field object. Otherwise, this was a lookup of an
146 * existing node and we don't want to create the field object again.
147 */
148 obj_desc = acpi_ns_get_attached_object (node);
149 if (obj_desc) {
150 return_ACPI_STATUS (AE_OK);
151 }
152
153 /*
154 * The Field definition is not fully parsed at this time.
155 * (We must save the address of the AML for the buffer and index operands)
156 */
157
158 /* Create the buffer field object */
159
160 obj_desc = acpi_ut_create_internal_object (ACPI_TYPE_BUFFER_FIELD);
161 if (!obj_desc) {
162 status = AE_NO_MEMORY;
163 goto cleanup;
164 }
165
166 /*
167 * Remember location in AML stream of the field unit
168 * opcode and operands -- since the buffer and index
169 * operands must be evaluated.
170 */
171 second_desc = obj_desc->common.next_object;
172 second_desc->extra.aml_start = op->named.data;
173 second_desc->extra.aml_length = op->named.length;
174 obj_desc->buffer_field.node = node;
175
176 /* Attach constructed field descriptors to parent node */
177
178 status = acpi_ns_attach_object (node, obj_desc, ACPI_TYPE_BUFFER_FIELD);
179 if (ACPI_FAILURE (status)) {
180 goto cleanup;
181 }
182
183
184cleanup:
185
186 /* Remove local reference to the object */
187
188 acpi_ut_remove_reference (obj_desc);
189 return_ACPI_STATUS (status);
190}
191
192
193/*******************************************************************************
194 *
195 * FUNCTION: acpi_ds_get_field_names
196 *
197 * PARAMETERS: Info - create_field info structure
198 * ` walk_state - Current method state
199 * Arg - First parser arg for the field name list
200 *
201 * RETURN: Status
202 *
203 * DESCRIPTION: Process all named fields in a field declaration. Names are
204 * entered into the namespace.
205 *
206 ******************************************************************************/
207
208acpi_status
209acpi_ds_get_field_names (
210 struct acpi_create_field_info *info,
211 struct acpi_walk_state *walk_state,
212 union acpi_parse_object *arg)
213{
214 acpi_status status;
215 acpi_integer position;
216
217
218 ACPI_FUNCTION_TRACE_PTR ("ds_get_field_names", info);
219
220
221 /* First field starts at bit zero */
222
223 info->field_bit_position = 0;
224
225 /* Process all elements in the field list (of parse nodes) */
226
227 while (arg) {
228 /*
229 * Three types of field elements are handled:
230 * 1) Offset - specifies a bit offset
231 * 2) access_as - changes the access mode
232 * 3) Name - Enters a new named field into the namespace
233 */
234 switch (arg->common.aml_opcode) {
235 case AML_INT_RESERVEDFIELD_OP:
236
237 position = (acpi_integer) info->field_bit_position
238 + (acpi_integer) arg->common.value.size;
239
240 if (position > ACPI_UINT32_MAX) {
241 ACPI_REPORT_ERROR (("Bit offset within field too large (> 0xFFFFFFFF)\n"));
242 return_ACPI_STATUS (AE_SUPPORT);
243 }
244
245 info->field_bit_position = (u32) position;
246 break;
247
248
249 case AML_INT_ACCESSFIELD_OP:
250
251 /*
252 * Get a new access_type and access_attribute -- to be used for all
253 * field units that follow, until field end or another access_as keyword.
254 *
255 * In field_flags, preserve the flag bits other than the ACCESS_TYPE bits
256 */
257 info->field_flags = (u8) ((info->field_flags & ~(AML_FIELD_ACCESS_TYPE_MASK)) |
258 ((u8) ((u32) arg->common.value.integer >> 8)));
259
260 info->attribute = (u8) (arg->common.value.integer);
261 break;
262
263
264 case AML_INT_NAMEDFIELD_OP:
265
266 /* Lookup the name */
267
268 status = acpi_ns_lookup (walk_state->scope_info,
269 (char *) &arg->named.name,
270 info->field_type, ACPI_IMODE_EXECUTE, ACPI_NS_DONT_OPEN_SCOPE,
271 walk_state, &info->field_node);
272 if (ACPI_FAILURE (status)) {
273 ACPI_REPORT_NSERROR ((char *) &arg->named.name, status);
274 if (status != AE_ALREADY_EXISTS) {
275 return_ACPI_STATUS (status);
276 }
277
278 /* Already exists, ignore error */
279 }
280 else {
281 arg->common.node = info->field_node;
282 info->field_bit_length = arg->common.value.size;
283
284 /* Create and initialize an object for the new Field Node */
285
286 status = acpi_ex_prep_field_value (info);
287 if (ACPI_FAILURE (status)) {
288 return_ACPI_STATUS (status);
289 }
290 }
291
292 /* Keep track of bit position for the next field */
293
294 position = (acpi_integer) info->field_bit_position
295 + (acpi_integer) arg->common.value.size;
296
297 if (position > ACPI_UINT32_MAX) {
298 ACPI_REPORT_ERROR (("Field [%4.4s] bit offset too large (> 0xFFFFFFFF)\n",
299 (char *) &info->field_node->name));
300 return_ACPI_STATUS (AE_SUPPORT);
301 }
302
303 info->field_bit_position += info->field_bit_length;
304 break;
305
306
307 default:
308
309 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Invalid opcode in field list: %X\n",
310 arg->common.aml_opcode));
311 return_ACPI_STATUS (AE_AML_BAD_OPCODE);
312 }
313
314 arg = arg->common.next;
315 }
316
317 return_ACPI_STATUS (AE_OK);
318}
319
320
321/*******************************************************************************
322 *
323 * FUNCTION: acpi_ds_create_field
324 *
325 * PARAMETERS: Op - Op containing the Field definition and args
326 * region_node - Object for the containing Operation Region
327 * ` walk_state - Current method state
328 *
329 * RETURN: Status
330 *
331 * DESCRIPTION: Create a new field in the specified operation region
332 *
333 ******************************************************************************/
334
335acpi_status
336acpi_ds_create_field (
337 union acpi_parse_object *op,
338 struct acpi_namespace_node *region_node,
339 struct acpi_walk_state *walk_state)
340{
341 acpi_status status;
342 union acpi_parse_object *arg;
343 struct acpi_create_field_info info;
344
345
346 ACPI_FUNCTION_TRACE_PTR ("ds_create_field", op);
347
348
349 /* First arg is the name of the parent op_region (must already exist) */
350
351 arg = op->common.value.arg;
352 if (!region_node) {
353 status = acpi_ns_lookup (walk_state->scope_info, arg->common.value.name,
354 ACPI_TYPE_REGION, ACPI_IMODE_EXECUTE,
355 ACPI_NS_SEARCH_PARENT, walk_state, &region_node);
356 if (ACPI_FAILURE (status)) {
357 ACPI_REPORT_NSERROR (arg->common.value.name, status);
358 return_ACPI_STATUS (status);
359 }
360 }
361
362 /* Second arg is the field flags */
363
364 arg = arg->common.next;
365 info.field_flags = (u8) arg->common.value.integer;
366 info.attribute = 0;
367
368 /* Each remaining arg is a Named Field */
369
370 info.field_type = ACPI_TYPE_LOCAL_REGION_FIELD;
371 info.region_node = region_node;
372
373 status = acpi_ds_get_field_names (&info, walk_state, arg->common.next);
374
375 return_ACPI_STATUS (status);
376}
377
378
379/*******************************************************************************
380 *
381 * FUNCTION: acpi_ds_init_field_objects
382 *
383 * PARAMETERS: Op - Op containing the Field definition and args
384 * ` walk_state - Current method state
385 *
386 * RETURN: Status
387 *
388 * DESCRIPTION: For each "Field Unit" name in the argument list that is
389 * part of the field declaration, enter the name into the
390 * namespace.
391 *
392 ******************************************************************************/
393
394acpi_status
395acpi_ds_init_field_objects (
396 union acpi_parse_object *op,
397 struct acpi_walk_state *walk_state)
398{
399 acpi_status status;
400 union acpi_parse_object *arg = NULL;
401 struct acpi_namespace_node *node;
402 u8 type = 0;
403
404
405 ACPI_FUNCTION_TRACE_PTR ("ds_init_field_objects", op);
406
407
408 switch (walk_state->opcode) {
409 case AML_FIELD_OP:
410 arg = acpi_ps_get_arg (op, 2);
411 type = ACPI_TYPE_LOCAL_REGION_FIELD;
412 break;
413
414 case AML_BANK_FIELD_OP:
415 arg = acpi_ps_get_arg (op, 4);
416 type = ACPI_TYPE_LOCAL_BANK_FIELD;
417 break;
418
419 case AML_INDEX_FIELD_OP:
420 arg = acpi_ps_get_arg (op, 3);
421 type = ACPI_TYPE_LOCAL_INDEX_FIELD;
422 break;
423
424 default:
425 return_ACPI_STATUS (AE_BAD_PARAMETER);
426 }
427
428 /*
429 * Walk the list of entries in the field_list
430 */
431 while (arg) {
432 /* Ignore OFFSET and ACCESSAS terms here */
433
434 if (arg->common.aml_opcode == AML_INT_NAMEDFIELD_OP) {
435 status = acpi_ns_lookup (walk_state->scope_info,
436 (char *) &arg->named.name,
437 type, ACPI_IMODE_LOAD_PASS1,
438 ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE | ACPI_NS_ERROR_IF_FOUND,
439 walk_state, &node);
440 if (ACPI_FAILURE (status)) {
441 ACPI_REPORT_NSERROR ((char *) &arg->named.name, status);
442 if (status != AE_ALREADY_EXISTS) {
443 return_ACPI_STATUS (status);
444 }
445
446 /* Name already exists, just ignore this error */
447
448 status = AE_OK;
449 }
450
451 arg->common.node = node;
452 }
453
454 /* Move to next field in the list */
455
456 arg = arg->common.next;
457 }
458
459 return_ACPI_STATUS (AE_OK);
460}
461
462
463/*******************************************************************************
464 *
465 * FUNCTION: acpi_ds_create_bank_field
466 *
467 * PARAMETERS: Op - Op containing the Field definition and args
468 * region_node - Object for the containing Operation Region
469 * ` walk_state - Current method state
470 *
471 * RETURN: Status
472 *
473 * DESCRIPTION: Create a new bank field in the specified operation region
474 *
475 ******************************************************************************/
476
477acpi_status
478acpi_ds_create_bank_field (
479 union acpi_parse_object *op,
480 struct acpi_namespace_node *region_node,
481 struct acpi_walk_state *walk_state)
482{
483 acpi_status status;
484 union acpi_parse_object *arg;
485 struct acpi_create_field_info info;
486
487
488 ACPI_FUNCTION_TRACE_PTR ("ds_create_bank_field", op);
489
490
491 /* First arg is the name of the parent op_region (must already exist) */
492
493 arg = op->common.value.arg;
494 if (!region_node) {
495 status = acpi_ns_lookup (walk_state->scope_info, arg->common.value.name,
496 ACPI_TYPE_REGION, ACPI_IMODE_EXECUTE,
497 ACPI_NS_SEARCH_PARENT, walk_state, &region_node);
498 if (ACPI_FAILURE (status)) {
499 ACPI_REPORT_NSERROR (arg->common.value.name, status);
500 return_ACPI_STATUS (status);
501 }
502 }
503
504 /* Second arg is the Bank Register (Field) (must already exist) */
505
506 arg = arg->common.next;
507 status = acpi_ns_lookup (walk_state->scope_info, arg->common.value.string,
508 ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
509 ACPI_NS_SEARCH_PARENT, walk_state, &info.register_node);
510 if (ACPI_FAILURE (status)) {
511 ACPI_REPORT_NSERROR (arg->common.value.string, status);
512 return_ACPI_STATUS (status);
513 }
514
515 /* Third arg is the bank_value */
516
517 arg = arg->common.next;
518 info.bank_value = (u32) arg->common.value.integer;
519
520 /* Fourth arg is the field flags */
521
522 arg = arg->common.next;
523 info.field_flags = (u8) arg->common.value.integer;
524
525 /* Each remaining arg is a Named Field */
526
527 info.field_type = ACPI_TYPE_LOCAL_BANK_FIELD;
528 info.region_node = region_node;
529
530 status = acpi_ds_get_field_names (&info, walk_state, arg->common.next);
531
532 return_ACPI_STATUS (status);
533}
534
535
536/*******************************************************************************
537 *
538 * FUNCTION: acpi_ds_create_index_field
539 *
540 * PARAMETERS: Op - Op containing the Field definition and args
541 * region_node - Object for the containing Operation Region
542 * ` walk_state - Current method state
543 *
544 * RETURN: Status
545 *
546 * DESCRIPTION: Create a new index field in the specified operation region
547 *
548 ******************************************************************************/
549
550acpi_status
551acpi_ds_create_index_field (
552 union acpi_parse_object *op,
553 struct acpi_namespace_node *region_node,
554 struct acpi_walk_state *walk_state)
555{
556 acpi_status status;
557 union acpi_parse_object *arg;
558 struct acpi_create_field_info info;
559
560
561 ACPI_FUNCTION_TRACE_PTR ("ds_create_index_field", op);
562
563
564 /* First arg is the name of the Index register (must already exist) */
565
566 arg = op->common.value.arg;
567 status = acpi_ns_lookup (walk_state->scope_info, arg->common.value.string,
568 ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
569 ACPI_NS_SEARCH_PARENT, walk_state, &info.register_node);
570 if (ACPI_FAILURE (status)) {
571 ACPI_REPORT_NSERROR (arg->common.value.string, status);
572 return_ACPI_STATUS (status);
573 }
574
575 /* Second arg is the data register (must already exist) */
576
577 arg = arg->common.next;
578 status = acpi_ns_lookup (walk_state->scope_info, arg->common.value.string,
579 ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
580 ACPI_NS_SEARCH_PARENT, walk_state, &info.data_register_node);
581 if (ACPI_FAILURE (status)) {
582 ACPI_REPORT_NSERROR (arg->common.value.string, status);
583 return_ACPI_STATUS (status);
584 }
585
586 /* Next arg is the field flags */
587
588 arg = arg->common.next;
589 info.field_flags = (u8) arg->common.value.integer;
590
591 /* Each remaining arg is a Named Field */
592
593 info.field_type = ACPI_TYPE_LOCAL_INDEX_FIELD;
594 info.region_node = region_node;
595
596 status = acpi_ds_get_field_names (&info, walk_state, arg->common.next);
597
598 return_ACPI_STATUS (status);
599}
600
601
diff --git a/drivers/acpi/dispatcher/dsinit.c b/drivers/acpi/dispatcher/dsinit.c
new file mode 100644
index 000000000000..b4d264dbbf67
--- /dev/null
+++ b/drivers/acpi/dispatcher/dsinit.c
@@ -0,0 +1,235 @@
1/******************************************************************************
2 *
3 * Module Name: dsinit - Object initialization namespace walk
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2005, R. Byron Moore
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
45#include <acpi/acpi.h>
46#include <acpi/acdispat.h>
47#include <acpi/acnamesp.h>
48
49#define _COMPONENT ACPI_DISPATCHER
50 ACPI_MODULE_NAME ("dsinit")
51
52
53/*******************************************************************************
54 *
55 * FUNCTION: acpi_ds_init_one_object
56 *
57 * PARAMETERS: obj_handle - Node
58 * Level - Current nesting level
59 * Context - Points to a init info struct
60 * return_value - Not used
61 *
62 * RETURN: Status
63 *
64 * DESCRIPTION: Callback from acpi_walk_namespace. Invoked for every object
65 * within the namespace.
66 *
67 * Currently, the only objects that require initialization are:
68 * 1) Methods
69 * 2) Operation Regions
70 *
71 ******************************************************************************/
72
73acpi_status
74acpi_ds_init_one_object (
75 acpi_handle obj_handle,
76 u32 level,
77 void *context,
78 void **return_value)
79{
80 acpi_object_type type;
81 acpi_status status;
82 struct acpi_init_walk_info *info = (struct acpi_init_walk_info *) context;
83
84
85 ACPI_FUNCTION_NAME ("ds_init_one_object");
86
87
88 /*
89 * We are only interested in objects owned by the table that
90 * was just loaded
91 */
92 if (((struct acpi_namespace_node *) obj_handle)->owner_id !=
93 info->table_desc->table_id) {
94 return (AE_OK);
95 }
96
97 info->object_count++;
98
99 /* And even then, we are only interested in a few object types */
100
101 type = acpi_ns_get_type (obj_handle);
102
103 switch (type) {
104 case ACPI_TYPE_REGION:
105
106 status = acpi_ds_initialize_region (obj_handle);
107 if (ACPI_FAILURE (status)) {
108 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Region %p [%4.4s] - Init failure, %s\n",
109 obj_handle, acpi_ut_get_node_name (obj_handle),
110 acpi_format_exception (status)));
111 }
112
113 info->op_region_count++;
114 break;
115
116
117 case ACPI_TYPE_METHOD:
118
119 info->method_count++;
120
121 /* Print a dot for each method unless we are going to print the entire pathname */
122
123 if (!(acpi_dbg_level & ACPI_LV_INIT_NAMES)) {
124 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT, "."));
125 }
126
127 /*
128 * Set the execution data width (32 or 64) based upon the
129 * revision number of the parent ACPI table.
130 * TBD: This is really for possible future support of integer width
131 * on a per-table basis. Currently, we just use a global for the width.
132 */
133 if (info->table_desc->pointer->revision == 1) {
134 ((struct acpi_namespace_node *) obj_handle)->flags |= ANOBJ_DATA_WIDTH_32;
135 }
136
137 /*
138 * Always parse methods to detect errors, we will delete
139 * the parse tree below
140 */
141 status = acpi_ds_parse_method (obj_handle);
142 if (ACPI_FAILURE (status)) {
143 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Method %p [%4.4s] - parse failure, %s\n",
144 obj_handle, acpi_ut_get_node_name (obj_handle),
145 acpi_format_exception (status)));
146
147 /* This parse failed, but we will continue parsing more methods */
148
149 break;
150 }
151
152 /*
153 * Delete the parse tree. We simply re-parse the method
154 * for every execution since there isn't much overhead
155 */
156 acpi_ns_delete_namespace_subtree (obj_handle);
157 acpi_ns_delete_namespace_by_owner (((struct acpi_namespace_node *) obj_handle)->object->method.owning_id);
158 break;
159
160
161 case ACPI_TYPE_DEVICE:
162
163 info->device_count++;
164 break;
165
166
167 default:
168 break;
169 }
170
171 /*
172 * We ignore errors from above, and always return OK, since
173 * we don't want to abort the walk on a single error.
174 */
175 return (AE_OK);
176}
177
178
179/*******************************************************************************
180 *
181 * FUNCTION: acpi_ds_initialize_objects
182 *
183 * PARAMETERS: table_desc - Descriptor for parent ACPI table
184 * start_node - Root of subtree to be initialized.
185 *
186 * RETURN: Status
187 *
188 * DESCRIPTION: Walk the namespace starting at "start_node" and perform any
189 * necessary initialization on the objects found therein
190 *
191 ******************************************************************************/
192
193acpi_status
194acpi_ds_initialize_objects (
195 struct acpi_table_desc *table_desc,
196 struct acpi_namespace_node *start_node)
197{
198 acpi_status status;
199 struct acpi_init_walk_info info;
200
201
202 ACPI_FUNCTION_TRACE ("ds_initialize_objects");
203
204
205 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
206 "**** Starting initialization of namespace objects ****\n"));
207 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT, "Parsing all Control Methods:"));
208
209 info.method_count = 0;
210 info.op_region_count = 0;
211 info.object_count = 0;
212 info.device_count = 0;
213 info.table_desc = table_desc;
214
215 /* Walk entire namespace from the supplied root */
216
217 status = acpi_walk_namespace (ACPI_TYPE_ANY, start_node, ACPI_UINT32_MAX,
218 acpi_ds_init_one_object, &info, NULL);
219 if (ACPI_FAILURE (status)) {
220 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "walk_namespace failed, %s\n",
221 acpi_format_exception (status)));
222 }
223
224 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT,
225 "\nTable [%4.4s](id %4.4X) - %hd Objects with %hd Devices %hd Methods %hd Regions\n",
226 table_desc->pointer->signature, table_desc->table_id, info.object_count,
227 info.device_count, info.method_count, info.op_region_count));
228
229 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
230 "%hd Methods, %hd Regions\n", info.method_count, info.op_region_count));
231
232 return_ACPI_STATUS (AE_OK);
233}
234
235
diff --git a/drivers/acpi/dispatcher/dsmethod.c b/drivers/acpi/dispatcher/dsmethod.c
new file mode 100644
index 000000000000..9f0456cb9bb5
--- /dev/null
+++ b/drivers/acpi/dispatcher/dsmethod.c
@@ -0,0 +1,597 @@
1/******************************************************************************
2 *
3 * Module Name: dsmethod - Parser/Interpreter interface - control method parsing
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2005, R. Byron Moore
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
45#include <acpi/acpi.h>
46#include <acpi/acparser.h>
47#include <acpi/amlcode.h>
48#include <acpi/acdispat.h>
49#include <acpi/acinterp.h>
50#include <acpi/acnamesp.h>
51
52
53#define _COMPONENT ACPI_DISPATCHER
54 ACPI_MODULE_NAME ("dsmethod")
55
56
57/*******************************************************************************
58 *
59 * FUNCTION: acpi_ds_parse_method
60 *
61 * PARAMETERS: obj_handle - Method node
62 *
63 * RETURN: Status
64 *
65 * DESCRIPTION: Call the parser and parse the AML that is associated with the
66 * method.
67 *
68 * MUTEX: Assumes parser is locked
69 *
70 ******************************************************************************/
71
72acpi_status
73acpi_ds_parse_method (
74 acpi_handle obj_handle)
75{
76 acpi_status status;
77 union acpi_operand_object *obj_desc;
78 union acpi_parse_object *op;
79 struct acpi_namespace_node *node;
80 acpi_owner_id owner_id;
81 struct acpi_walk_state *walk_state;
82
83
84 ACPI_FUNCTION_TRACE_PTR ("ds_parse_method", obj_handle);
85
86
87 /* Parameter Validation */
88
89 if (!obj_handle) {
90 return_ACPI_STATUS (AE_NULL_ENTRY);
91 }
92
93 ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "**** Parsing [%4.4s] **** named_obj=%p\n",
94 acpi_ut_get_node_name (obj_handle), obj_handle));
95
96 /* Extract the method object from the method Node */
97
98 node = (struct acpi_namespace_node *) obj_handle;
99 obj_desc = acpi_ns_get_attached_object (node);
100 if (!obj_desc) {
101 return_ACPI_STATUS (AE_NULL_OBJECT);
102 }
103
104 /* Create a mutex for the method if there is a concurrency limit */
105
106 if ((obj_desc->method.concurrency != ACPI_INFINITE_CONCURRENCY) &&
107 (!obj_desc->method.semaphore)) {
108 status = acpi_os_create_semaphore (obj_desc->method.concurrency,
109 obj_desc->method.concurrency,
110 &obj_desc->method.semaphore);
111 if (ACPI_FAILURE (status)) {
112 return_ACPI_STATUS (status);
113 }
114 }
115
116 /*
117 * Allocate a new parser op to be the root of the parsed
118 * method tree
119 */
120 op = acpi_ps_alloc_op (AML_METHOD_OP);
121 if (!op) {
122 return_ACPI_STATUS (AE_NO_MEMORY);
123 }
124
125 /* Init new op with the method name and pointer back to the Node */
126
127 acpi_ps_set_name (op, node->name.integer);
128 op->common.node = node;
129
130 /*
131 * Get a new owner_id for objects created by this method. Namespace
132 * objects (such as Operation Regions) can be created during the
133 * first pass parse.
134 */
135 owner_id = acpi_ut_allocate_owner_id (ACPI_OWNER_TYPE_METHOD);
136 obj_desc->method.owning_id = owner_id;
137
138 /* Create and initialize a new walk state */
139
140 walk_state = acpi_ds_create_walk_state (owner_id, NULL, NULL, NULL);
141 if (!walk_state) {
142 return_ACPI_STATUS (AE_NO_MEMORY);
143 }
144
145 status = acpi_ds_init_aml_walk (walk_state, op, node,
146 obj_desc->method.aml_start,
147 obj_desc->method.aml_length, NULL, 1);
148 if (ACPI_FAILURE (status)) {
149 acpi_ds_delete_walk_state (walk_state);
150 return_ACPI_STATUS (status);
151 }
152
153 /*
154 * Parse the method, first pass
155 *
156 * The first pass load is where newly declared named objects are
157 * added into the namespace. Actual evaluation of
158 * the named objects (what would be called a "second
159 * pass") happens during the actual execution of the
160 * method so that operands to the named objects can
161 * take on dynamic run-time values.
162 */
163 status = acpi_ps_parse_aml (walk_state);
164 if (ACPI_FAILURE (status)) {
165 return_ACPI_STATUS (status);
166 }
167
168 ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
169 "**** [%4.4s] Parsed **** named_obj=%p Op=%p\n",
170 acpi_ut_get_node_name (obj_handle), obj_handle, op));
171
172 acpi_ps_delete_parse_tree (op);
173 return_ACPI_STATUS (status);
174}
175
176
177/*******************************************************************************
178 *
179 * FUNCTION: acpi_ds_begin_method_execution
180 *
181 * PARAMETERS: method_node - Node of the method
182 * obj_desc - The method object
183 * calling_method_node - Caller of this method (if non-null)
184 *
185 * RETURN: Status
186 *
187 * DESCRIPTION: Prepare a method for execution. Parses the method if necessary,
188 * increments the thread count, and waits at the method semaphore
189 * for clearance to execute.
190 *
191 ******************************************************************************/
192
193acpi_status
194acpi_ds_begin_method_execution (
195 struct acpi_namespace_node *method_node,
196 union acpi_operand_object *obj_desc,
197 struct acpi_namespace_node *calling_method_node)
198{
199 acpi_status status = AE_OK;
200
201
202 ACPI_FUNCTION_TRACE_PTR ("ds_begin_method_execution", method_node);
203
204
205 if (!method_node) {
206 return_ACPI_STATUS (AE_NULL_ENTRY);
207 }
208
209 /*
210 * If there is a concurrency limit on this method, we need to
211 * obtain a unit from the method semaphore.
212 */
213 if (obj_desc->method.semaphore) {
214 /*
215 * Allow recursive method calls, up to the reentrancy/concurrency
216 * limit imposed by the SERIALIZED rule and the sync_level method
217 * parameter.
218 *
219 * The point of this code is to avoid permanently blocking a
220 * thread that is making recursive method calls.
221 */
222 if (method_node == calling_method_node) {
223 if (obj_desc->method.thread_count >= obj_desc->method.concurrency) {
224 return_ACPI_STATUS (AE_AML_METHOD_LIMIT);
225 }
226 }
227
228 /*
229 * Get a unit from the method semaphore. This releases the
230 * interpreter if we block
231 */
232 status = acpi_ex_system_wait_semaphore (obj_desc->method.semaphore,
233 ACPI_WAIT_FOREVER);
234 }
235
236 /*
237 * Increment the method parse tree thread count since it has been
238 * reentered one more time (even if it is the same thread)
239 */
240 obj_desc->method.thread_count++;
241 return_ACPI_STATUS (status);
242}
243
244
245/*******************************************************************************
246 *
247 * FUNCTION: acpi_ds_call_control_method
248 *
249 * PARAMETERS: Thread - Info for this thread
250 * this_walk_state - Current walk state
251 * Op - Current Op to be walked
252 *
253 * RETURN: Status
254 *
255 * DESCRIPTION: Transfer execution to a called control method
256 *
257 ******************************************************************************/
258
259acpi_status
260acpi_ds_call_control_method (
261 struct acpi_thread_state *thread,
262 struct acpi_walk_state *this_walk_state,
263 union acpi_parse_object *op)
264{
265 acpi_status status;
266 struct acpi_namespace_node *method_node;
267 struct acpi_walk_state *next_walk_state;
268 union acpi_operand_object *obj_desc;
269 struct acpi_parameter_info info;
270 u32 i;
271
272
273 ACPI_FUNCTION_TRACE_PTR ("ds_call_control_method", this_walk_state);
274
275 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Execute method %p, currentstate=%p\n",
276 this_walk_state->prev_op, this_walk_state));
277
278 /*
279 * Get the namespace entry for the control method we are about to call
280 */
281 method_node = this_walk_state->method_call_node;
282 if (!method_node) {
283 return_ACPI_STATUS (AE_NULL_ENTRY);
284 }
285
286 obj_desc = acpi_ns_get_attached_object (method_node);
287 if (!obj_desc) {
288 return_ACPI_STATUS (AE_NULL_OBJECT);
289 }
290
291 obj_desc->method.owning_id = acpi_ut_allocate_owner_id (ACPI_OWNER_TYPE_METHOD);
292
293 /* Init for new method, wait on concurrency semaphore */
294
295 status = acpi_ds_begin_method_execution (method_node, obj_desc,
296 this_walk_state->method_node);
297 if (ACPI_FAILURE (status)) {
298 return_ACPI_STATUS (status);
299 }
300
301 if (!(obj_desc->method.method_flags & AML_METHOD_INTERNAL_ONLY)) {
302 /* 1) Parse: Create a new walk state for the preempting walk */
303
304 next_walk_state = acpi_ds_create_walk_state (obj_desc->method.owning_id,
305 op, obj_desc, NULL);
306 if (!next_walk_state) {
307 return_ACPI_STATUS (AE_NO_MEMORY);
308 }
309
310 /* Create and init a Root Node */
311
312 op = acpi_ps_create_scope_op ();
313 if (!op) {
314 status = AE_NO_MEMORY;
315 goto cleanup;
316 }
317
318 status = acpi_ds_init_aml_walk (next_walk_state, op, method_node,
319 obj_desc->method.aml_start, obj_desc->method.aml_length,
320 NULL, 1);
321 if (ACPI_FAILURE (status)) {
322 acpi_ds_delete_walk_state (next_walk_state);
323 goto cleanup;
324 }
325
326 /* Begin AML parse */
327
328 status = acpi_ps_parse_aml (next_walk_state);
329 acpi_ps_delete_parse_tree (op);
330 }
331
332 /* 2) Execute: Create a new state for the preempting walk */
333
334 next_walk_state = acpi_ds_create_walk_state (obj_desc->method.owning_id,
335 NULL, obj_desc, thread);
336 if (!next_walk_state) {
337 status = AE_NO_MEMORY;
338 goto cleanup;
339 }
340 /*
341 * The resolved arguments were put on the previous walk state's operand
342 * stack. Operands on the previous walk state stack always
343 * start at index 0.
344 * Null terminate the list of arguments
345 */
346 this_walk_state->operands [this_walk_state->num_operands] = NULL;
347
348 info.parameters = &this_walk_state->operands[0];
349 info.parameter_type = ACPI_PARAM_ARGS;
350
351 status = acpi_ds_init_aml_walk (next_walk_state, NULL, method_node,
352 obj_desc->method.aml_start, obj_desc->method.aml_length,
353 &info, 3);
354 if (ACPI_FAILURE (status)) {
355 goto cleanup;
356 }
357
358 /*
359 * Delete the operands on the previous walkstate operand stack
360 * (they were copied to new objects)
361 */
362 for (i = 0; i < obj_desc->method.param_count; i++) {
363 acpi_ut_remove_reference (this_walk_state->operands [i]);
364 this_walk_state->operands [i] = NULL;
365 }
366
367 /* Clear the operand stack */
368
369 this_walk_state->num_operands = 0;
370
371 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
372 "Starting nested execution, newstate=%p\n", next_walk_state));
373
374 if (obj_desc->method.method_flags & AML_METHOD_INTERNAL_ONLY) {
375 status = obj_desc->method.implementation (next_walk_state);
376 return_ACPI_STATUS (status);
377 }
378
379 return_ACPI_STATUS (AE_OK);
380
381
382 /* On error, we must delete the new walk state */
383
384cleanup:
385 if (next_walk_state && (next_walk_state->method_desc)) {
386 /* Decrement the thread count on the method parse tree */
387
388 next_walk_state->method_desc->method.thread_count--;
389 }
390 (void) acpi_ds_terminate_control_method (next_walk_state);
391 acpi_ds_delete_walk_state (next_walk_state);
392 return_ACPI_STATUS (status);
393}
394
395
396/*******************************************************************************
397 *
398 * FUNCTION: acpi_ds_restart_control_method
399 *
400 * PARAMETERS: walk_state - State for preempted method (caller)
401 * return_desc - Return value from the called method
402 *
403 * RETURN: Status
404 *
405 * DESCRIPTION: Restart a method that was preempted by another (nested) method
406 * invocation. Handle the return value (if any) from the callee.
407 *
408 ******************************************************************************/
409
410acpi_status
411acpi_ds_restart_control_method (
412 struct acpi_walk_state *walk_state,
413 union acpi_operand_object *return_desc)
414{
415 acpi_status status;
416
417
418 ACPI_FUNCTION_TRACE_PTR ("ds_restart_control_method", walk_state);
419
420
421 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
422 "****Restart [%4.4s] Op %p return_value_from_callee %p\n",
423 (char *) &walk_state->method_node->name, walk_state->method_call_op,
424 return_desc));
425
426 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
427 " return_from_this_method_used?=%X res_stack %p Walk %p\n",
428 walk_state->return_used,
429 walk_state->results, walk_state));
430
431 /* Did the called method return a value? */
432
433 if (return_desc) {
434 /* Are we actually going to use the return value? */
435
436 if (walk_state->return_used) {
437 /* Save the return value from the previous method */
438
439 status = acpi_ds_result_push (return_desc, walk_state);
440 if (ACPI_FAILURE (status)) {
441 acpi_ut_remove_reference (return_desc);
442 return_ACPI_STATUS (status);
443 }
444
445 /*
446 * Save as THIS method's return value in case it is returned
447 * immediately to yet another method
448 */
449 walk_state->return_desc = return_desc;
450 }
451
452 /*
453 * The following code is the
454 * optional support for a so-called "implicit return". Some AML code
455 * assumes that the last value of the method is "implicitly" returned
456 * to the caller. Just save the last result as the return value.
457 * NOTE: this is optional because the ASL language does not actually
458 * support this behavior.
459 */
460 else if (!acpi_ds_do_implicit_return (return_desc, walk_state, FALSE)) {
461 /*
462 * Delete the return value if it will not be used by the
463 * calling method
464 */
465 acpi_ut_remove_reference (return_desc);
466 }
467 }
468
469 return_ACPI_STATUS (AE_OK);
470}
471
472
473/*******************************************************************************
474 *
475 * FUNCTION: acpi_ds_terminate_control_method
476 *
477 * PARAMETERS: walk_state - State of the method
478 *
479 * RETURN: Status
480 *
481 * DESCRIPTION: Terminate a control method. Delete everything that the method
482 * created, delete all locals and arguments, and delete the parse
483 * tree if requested.
484 *
485 ******************************************************************************/
486
487acpi_status
488acpi_ds_terminate_control_method (
489 struct acpi_walk_state *walk_state)
490{
491 union acpi_operand_object *obj_desc;
492 struct acpi_namespace_node *method_node;
493 acpi_status status;
494
495
496 ACPI_FUNCTION_TRACE_PTR ("ds_terminate_control_method", walk_state);
497
498
499 if (!walk_state) {
500 return (AE_BAD_PARAMETER);
501 }
502
503 /* The current method object was saved in the walk state */
504
505 obj_desc = walk_state->method_desc;
506 if (!obj_desc) {
507 return_ACPI_STATUS (AE_OK);
508 }
509
510 /* Delete all arguments and locals */
511
512 acpi_ds_method_data_delete_all (walk_state);
513
514 /*
515 * Lock the parser while we terminate this method.
516 * If this is the last thread executing the method,
517 * we have additional cleanup to perform
518 */
519 status = acpi_ut_acquire_mutex (ACPI_MTX_PARSER);
520 if (ACPI_FAILURE (status)) {
521 return_ACPI_STATUS (status);
522 }
523
524 /* Signal completion of the execution of this method if necessary */
525
526 if (walk_state->method_desc->method.semaphore) {
527 status = acpi_os_signal_semaphore (
528 walk_state->method_desc->method.semaphore, 1);
529 if (ACPI_FAILURE (status)) {
530 ACPI_REPORT_ERROR (("Could not signal method semaphore\n"));
531 status = AE_OK;
532
533 /* Ignore error and continue cleanup */
534 }
535 }
536
537 if (walk_state->method_desc->method.thread_count) {
538 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
539 "*** Not deleting method namespace, there are still %d threads\n",
540 walk_state->method_desc->method.thread_count));
541 }
542
543 if (!walk_state->method_desc->method.thread_count) {
544 /*
545 * Support to dynamically change a method from not_serialized to
546 * Serialized if it appears that the method is written foolishly and
547 * does not support multiple thread execution. The best example of this
548 * is if such a method creates namespace objects and blocks. A second
549 * thread will fail with an AE_ALREADY_EXISTS exception
550 *
551 * This code is here because we must wait until the last thread exits
552 * before creating the synchronization semaphore.
553 */
554 if ((walk_state->method_desc->method.concurrency == 1) &&
555 (!walk_state->method_desc->method.semaphore)) {
556 status = acpi_os_create_semaphore (1,
557 1,
558 &walk_state->method_desc->method.semaphore);
559 }
560
561 /*
562 * There are no more threads executing this method. Perform
563 * additional cleanup.
564 *
565 * The method Node is stored in the walk state
566 */
567 method_node = walk_state->method_node;
568
569 /*
570 * Delete any namespace entries created immediately underneath
571 * the method
572 */
573 status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE);
574 if (ACPI_FAILURE (status)) {
575 return_ACPI_STATUS (status);
576 }
577
578 if (method_node->child) {
579 acpi_ns_delete_namespace_subtree (method_node);
580 }
581
582 /*
583 * Delete any namespace entries created anywhere else within
584 * the namespace
585 */
586 acpi_ns_delete_namespace_by_owner (walk_state->method_desc->method.owning_id);
587 status = acpi_ut_release_mutex (ACPI_MTX_NAMESPACE);
588 if (ACPI_FAILURE (status)) {
589 return_ACPI_STATUS (status);
590 }
591 }
592
593 status = acpi_ut_release_mutex (ACPI_MTX_PARSER);
594 return_ACPI_STATUS (status);
595}
596
597
diff --git a/drivers/acpi/dispatcher/dsmthdat.c b/drivers/acpi/dispatcher/dsmthdat.c
new file mode 100644
index 000000000000..f31d095f9833
--- /dev/null
+++ b/drivers/acpi/dispatcher/dsmthdat.c
@@ -0,0 +1,715 @@
1/*******************************************************************************
2 *
3 * Module Name: dsmthdat - control method arguments and local variables
4 *
5 ******************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2005, R. Byron Moore
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
45#include <acpi/acpi.h>
46#include <acpi/acdispat.h>
47#include <acpi/amlcode.h>
48#include <acpi/acnamesp.h>
49#include <acpi/acinterp.h>
50
51
52#define _COMPONENT ACPI_DISPATCHER
53 ACPI_MODULE_NAME ("dsmthdat")
54
55
56/*******************************************************************************
57 *
58 * FUNCTION: acpi_ds_method_data_init
59 *
60 * PARAMETERS: walk_state - Current walk state object
61 *
62 * RETURN: Status
63 *
64 * DESCRIPTION: Initialize the data structures that hold the method's arguments
65 * and locals. The data struct is an array of NTEs for each.
66 * This allows ref_of and de_ref_of to work properly for these
67 * special data types.
68 *
69 * NOTES: walk_state fields are initialized to zero by the
70 * ACPI_MEM_CALLOCATE().
71 *
72 * A pseudo-Namespace Node is assigned to each argument and local
73 * so that ref_of() can return a pointer to the Node.
74 *
75 ******************************************************************************/
76
77void
78acpi_ds_method_data_init (
79 struct acpi_walk_state *walk_state)
80{
81 u32 i;
82
83
84 ACPI_FUNCTION_TRACE ("ds_method_data_init");
85
86
87 /* Init the method arguments */
88
89 for (i = 0; i < ACPI_METHOD_NUM_ARGS; i++) {
90 ACPI_MOVE_32_TO_32 (&walk_state->arguments[i].name,
91 NAMEOF_ARG_NTE);
92 walk_state->arguments[i].name.integer |= (i << 24);
93 walk_state->arguments[i].descriptor = ACPI_DESC_TYPE_NAMED;
94 walk_state->arguments[i].type = ACPI_TYPE_ANY;
95 walk_state->arguments[i].flags = ANOBJ_END_OF_PEER_LIST | ANOBJ_METHOD_ARG;
96 }
97
98 /* Init the method locals */
99
100 for (i = 0; i < ACPI_METHOD_NUM_LOCALS; i++) {
101 ACPI_MOVE_32_TO_32 (&walk_state->local_variables[i].name,
102 NAMEOF_LOCAL_NTE);
103
104 walk_state->local_variables[i].name.integer |= (i << 24);
105 walk_state->local_variables[i].descriptor = ACPI_DESC_TYPE_NAMED;
106 walk_state->local_variables[i].type = ACPI_TYPE_ANY;
107 walk_state->local_variables[i].flags = ANOBJ_END_OF_PEER_LIST | ANOBJ_METHOD_LOCAL;
108 }
109
110 return_VOID;
111}
112
113
114/*******************************************************************************
115 *
116 * FUNCTION: acpi_ds_method_data_delete_all
117 *
118 * PARAMETERS: walk_state - Current walk state object
119 *
120 * RETURN: None
121 *
122 * DESCRIPTION: Delete method locals and arguments. Arguments are only
123 * deleted if this method was called from another method.
124 *
125 ******************************************************************************/
126
127void
128acpi_ds_method_data_delete_all (
129 struct acpi_walk_state *walk_state)
130{
131 u32 index;
132
133
134 ACPI_FUNCTION_TRACE ("ds_method_data_delete_all");
135
136
137 /* Detach the locals */
138
139 for (index = 0; index < ACPI_METHOD_NUM_LOCALS; index++) {
140 if (walk_state->local_variables[index].object) {
141 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Deleting Local%d=%p\n",
142 index, walk_state->local_variables[index].object));
143
144 /* Detach object (if present) and remove a reference */
145
146 acpi_ns_detach_object (&walk_state->local_variables[index]);
147 }
148 }
149
150 /* Detach the arguments */
151
152 for (index = 0; index < ACPI_METHOD_NUM_ARGS; index++) {
153 if (walk_state->arguments[index].object) {
154 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Deleting Arg%d=%p\n",
155 index, walk_state->arguments[index].object));
156
157 /* Detach object (if present) and remove a reference */
158
159 acpi_ns_detach_object (&walk_state->arguments[index]);
160 }
161 }
162
163 return_VOID;
164}
165
166
167/*******************************************************************************
168 *
169 * FUNCTION: acpi_ds_method_data_init_args
170 *
171 * PARAMETERS: *Params - Pointer to a parameter list for the method
172 * max_param_count - The arg count for this method
173 * walk_state - Current walk state object
174 *
175 * RETURN: Status
176 *
177 * DESCRIPTION: Initialize arguments for a method. The parameter list is a list
178 * of ACPI operand objects, either null terminated or whose length
179 * is defined by max_param_count.
180 *
181 ******************************************************************************/
182
183acpi_status
184acpi_ds_method_data_init_args (
185 union acpi_operand_object **params,
186 u32 max_param_count,
187 struct acpi_walk_state *walk_state)
188{
189 acpi_status status;
190 u32 index = 0;
191
192
193 ACPI_FUNCTION_TRACE_PTR ("ds_method_data_init_args", params);
194
195
196 if (!params) {
197 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "No param list passed to method\n"));
198 return_ACPI_STATUS (AE_OK);
199 }
200
201 /* Copy passed parameters into the new method stack frame */
202
203 while ((index < ACPI_METHOD_NUM_ARGS) && (index < max_param_count) && params[index]) {
204 /*
205 * A valid parameter.
206 * Store the argument in the method/walk descriptor.
207 * Do not copy the arg in order to implement call by reference
208 */
209 status = acpi_ds_method_data_set_value (AML_ARG_OP, index, params[index], walk_state);
210 if (ACPI_FAILURE (status)) {
211 return_ACPI_STATUS (status);
212 }
213
214 index++;
215 }
216
217 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "%d args passed to method\n", index));
218 return_ACPI_STATUS (AE_OK);
219}
220
221
222/*******************************************************************************
223 *
224 * FUNCTION: acpi_ds_method_data_get_node
225 *
226 * PARAMETERS: Opcode - Either AML_LOCAL_OP or AML_ARG_OP
227 * Index - which local_var or argument whose type
228 * to get
229 * walk_state - Current walk state object
230 *
231 * RETURN: Get the Node associated with a local or arg.
232 *
233 ******************************************************************************/
234
235acpi_status
236acpi_ds_method_data_get_node (
237 u16 opcode,
238 u32 index,
239 struct acpi_walk_state *walk_state,
240 struct acpi_namespace_node **node)
241{
242 ACPI_FUNCTION_TRACE ("ds_method_data_get_node");
243
244
245 /*
246 * Method Locals and Arguments are supported
247 */
248 switch (opcode) {
249 case AML_LOCAL_OP:
250
251 if (index > ACPI_METHOD_MAX_LOCAL) {
252 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Local index %d is invalid (max %d)\n",
253 index, ACPI_METHOD_MAX_LOCAL));
254 return_ACPI_STATUS (AE_AML_INVALID_INDEX);
255 }
256
257 /* Return a pointer to the pseudo-node */
258
259 *node = &walk_state->local_variables[index];
260 break;
261
262 case AML_ARG_OP:
263
264 if (index > ACPI_METHOD_MAX_ARG) {
265 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Arg index %d is invalid (max %d)\n",
266 index, ACPI_METHOD_MAX_ARG));
267 return_ACPI_STATUS (AE_AML_INVALID_INDEX);
268 }
269
270 /* Return a pointer to the pseudo-node */
271
272 *node = &walk_state->arguments[index];
273 break;
274
275 default:
276 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Opcode %d is invalid\n", opcode));
277 return_ACPI_STATUS (AE_AML_BAD_OPCODE);
278 }
279
280 return_ACPI_STATUS (AE_OK);
281}
282
283
284/*******************************************************************************
285 *
286 * FUNCTION: acpi_ds_method_data_set_value
287 *
288 * PARAMETERS: Opcode - Either AML_LOCAL_OP or AML_ARG_OP
289 * Index - which local_var or argument to get
290 * Object - Object to be inserted into the stack entry
291 * walk_state - Current walk state object
292 *
293 * RETURN: Status
294 *
295 * DESCRIPTION: Insert an object onto the method stack at entry Opcode:Index.
296 * Note: There is no "implicit conversion" for locals.
297 *
298 ******************************************************************************/
299
300acpi_status
301acpi_ds_method_data_set_value (
302 u16 opcode,
303 u32 index,
304 union acpi_operand_object *object,
305 struct acpi_walk_state *walk_state)
306{
307 acpi_status status;
308 struct acpi_namespace_node *node;
309
310
311 ACPI_FUNCTION_TRACE ("ds_method_data_set_value");
312
313
314 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
315 "new_obj %p Opcode %X, Refs=%d [%s]\n", object,
316 opcode, object->common.reference_count,
317 acpi_ut_get_type_name (object->common.type)));
318
319 /* Get the namespace node for the arg/local */
320
321 status = acpi_ds_method_data_get_node (opcode, index, walk_state, &node);
322 if (ACPI_FAILURE (status)) {
323 return_ACPI_STATUS (status);
324 }
325
326 /*
327 * Increment ref count so object can't be deleted while installed.
328 * NOTE: We do not copy the object in order to preserve the call by
329 * reference semantics of ACPI Control Method invocation.
330 * (See ACPI specification 2.0_c)
331 */
332 acpi_ut_add_reference (object);
333
334 /* Install the object */
335
336 node->object = object;
337 return_ACPI_STATUS (status);
338}
339
340
341/*******************************************************************************
342 *
343 * FUNCTION: acpi_ds_method_data_get_type
344 *
345 * PARAMETERS: Opcode - Either AML_LOCAL_OP or AML_ARG_OP
346 * Index - which local_var or argument whose type
347 * to get
348 * walk_state - Current walk state object
349 *
350 * RETURN: Data type of current value of the selected Arg or Local
351 *
352 ******************************************************************************/
353#ifdef ACPI_FUTURE_USAGE
354acpi_object_type
355acpi_ds_method_data_get_type (
356 u16 opcode,
357 u32 index,
358 struct acpi_walk_state *walk_state)
359{
360 acpi_status status;
361 struct acpi_namespace_node *node;
362 union acpi_operand_object *object;
363
364
365 ACPI_FUNCTION_TRACE ("ds_method_data_get_type");
366
367
368 /* Get the namespace node for the arg/local */
369
370 status = acpi_ds_method_data_get_node (opcode, index, walk_state, &node);
371 if (ACPI_FAILURE (status)) {
372 return_VALUE ((ACPI_TYPE_NOT_FOUND));
373 }
374
375 /* Get the object */
376
377 object = acpi_ns_get_attached_object (node);
378 if (!object) {
379 /* Uninitialized local/arg, return TYPE_ANY */
380
381 return_VALUE (ACPI_TYPE_ANY);
382 }
383
384 /* Get the object type */
385
386 return_VALUE (ACPI_GET_OBJECT_TYPE (object));
387}
388#endif /* ACPI_FUTURE_USAGE */
389
390
391/*******************************************************************************
392 *
393 * FUNCTION: acpi_ds_method_data_get_value
394 *
395 * PARAMETERS: Opcode - Either AML_LOCAL_OP or AML_ARG_OP
396 * Index - which local_var or argument to get
397 * walk_state - Current walk state object
398 * *dest_desc - Ptr to Descriptor into which selected Arg
399 * or Local value should be copied
400 *
401 * RETURN: Status
402 *
403 * DESCRIPTION: Retrieve value of selected Arg or Local from the method frame
404 * at the current top of the method stack.
405 * Used only in acpi_ex_resolve_to_value().
406 *
407 ******************************************************************************/
408
409acpi_status
410acpi_ds_method_data_get_value (
411 u16 opcode,
412 u32 index,
413 struct acpi_walk_state *walk_state,
414 union acpi_operand_object **dest_desc)
415{
416 acpi_status status;
417 struct acpi_namespace_node *node;
418 union acpi_operand_object *object;
419
420
421 ACPI_FUNCTION_TRACE ("ds_method_data_get_value");
422
423
424 /* Validate the object descriptor */
425
426 if (!dest_desc) {
427 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Null object descriptor pointer\n"));
428 return_ACPI_STATUS (AE_BAD_PARAMETER);
429 }
430
431 /* Get the namespace node for the arg/local */
432
433 status = acpi_ds_method_data_get_node (opcode, index, walk_state, &node);
434 if (ACPI_FAILURE (status)) {
435 return_ACPI_STATUS (status);
436 }
437
438 /* Get the object from the node */
439
440 object = node->object;
441
442 /* Examine the returned object, it must be valid. */
443
444 if (!object) {
445 /*
446 * Index points to uninitialized object.
447 * This means that either 1) The expected argument was
448 * not passed to the method, or 2) A local variable
449 * was referenced by the method (via the ASL)
450 * before it was initialized. Either case is an error.
451 */
452
453 /* If slack enabled, init the local_x/arg_x to an Integer of value zero */
454
455 if (acpi_gbl_enable_interpreter_slack) {
456 object = acpi_ut_create_internal_object (ACPI_TYPE_INTEGER);
457 if (!object) {
458 return_ACPI_STATUS (AE_NO_MEMORY);
459 }
460
461 object->integer.value = 0;
462 node->object = object;
463 }
464
465 /* Otherwise, return the error */
466
467 else switch (opcode) {
468 case AML_ARG_OP:
469
470 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Uninitialized Arg[%d] at node %p\n",
471 index, node));
472
473 return_ACPI_STATUS (AE_AML_UNINITIALIZED_ARG);
474
475 case AML_LOCAL_OP:
476
477 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Uninitialized Local[%d] at node %p\n",
478 index, node));
479
480 return_ACPI_STATUS (AE_AML_UNINITIALIZED_LOCAL);
481
482 default:
483 ACPI_REPORT_ERROR (("Not Arg/Local opcode: %X\n", opcode));
484 return_ACPI_STATUS (AE_AML_INTERNAL);
485 }
486 }
487
488 /*
489 * The Index points to an initialized and valid object.
490 * Return an additional reference to the object
491 */
492 *dest_desc = object;
493 acpi_ut_add_reference (object);
494
495 return_ACPI_STATUS (AE_OK);
496}
497
498
499/*******************************************************************************
500 *
501 * FUNCTION: acpi_ds_method_data_delete_value
502 *
503 * PARAMETERS: Opcode - Either AML_LOCAL_OP or AML_ARG_OP
504 * Index - which local_var or argument to delete
505 * walk_state - Current walk state object
506 *
507 * RETURN: None
508 *
509 * DESCRIPTION: Delete the entry at Opcode:Index on the method stack. Inserts
510 * a null into the stack slot after the object is deleted.
511 *
512 ******************************************************************************/
513
514void
515acpi_ds_method_data_delete_value (
516 u16 opcode,
517 u32 index,
518 struct acpi_walk_state *walk_state)
519{
520 acpi_status status;
521 struct acpi_namespace_node *node;
522 union acpi_operand_object *object;
523
524
525 ACPI_FUNCTION_TRACE ("ds_method_data_delete_value");
526
527
528 /* Get the namespace node for the arg/local */
529
530 status = acpi_ds_method_data_get_node (opcode, index, walk_state, &node);
531 if (ACPI_FAILURE (status)) {
532 return_VOID;
533 }
534
535 /* Get the associated object */
536
537 object = acpi_ns_get_attached_object (node);
538
539 /*
540 * Undefine the Arg or Local by setting its descriptor
541 * pointer to NULL. Locals/Args can contain both
542 * ACPI_OPERAND_OBJECTS and ACPI_NAMESPACE_NODEs
543 */
544 node->object = NULL;
545
546 if ((object) &&
547 (ACPI_GET_DESCRIPTOR_TYPE (object) == ACPI_DESC_TYPE_OPERAND)) {
548 /*
549 * There is a valid object.
550 * Decrement the reference count by one to balance the
551 * increment when the object was stored.
552 */
553 acpi_ut_remove_reference (object);
554 }
555
556 return_VOID;
557}
558
559
560/*******************************************************************************
561 *
562 * FUNCTION: acpi_ds_store_object_to_local
563 *
564 * PARAMETERS: Opcode - Either AML_LOCAL_OP or AML_ARG_OP
565 * Index - which local_var or argument to set
566 * obj_desc - Value to be stored
567 * walk_state - Current walk state
568 *
569 * RETURN: Status
570 *
571 * DESCRIPTION: Store a value in an Arg or Local. The obj_desc is installed
572 * as the new value for the Arg or Local and the reference count
573 * for obj_desc is incremented.
574 *
575 ******************************************************************************/
576
577acpi_status
578acpi_ds_store_object_to_local (
579 u16 opcode,
580 u32 index,
581 union acpi_operand_object *obj_desc,
582 struct acpi_walk_state *walk_state)
583{
584 acpi_status status;
585 struct acpi_namespace_node *node;
586 union acpi_operand_object *current_obj_desc;
587 union acpi_operand_object *new_obj_desc;
588
589
590 ACPI_FUNCTION_TRACE ("ds_store_object_to_local");
591 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Opcode=%X Index=%d Obj=%p\n",
592 opcode, index, obj_desc));
593
594 /* Parameter validation */
595
596 if (!obj_desc) {
597 return_ACPI_STATUS (AE_BAD_PARAMETER);
598 }
599
600 /* Get the namespace node for the arg/local */
601
602 status = acpi_ds_method_data_get_node (opcode, index, walk_state, &node);
603 if (ACPI_FAILURE (status)) {
604 return_ACPI_STATUS (status);
605 }
606
607 current_obj_desc = acpi_ns_get_attached_object (node);
608 if (current_obj_desc == obj_desc) {
609 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Obj=%p already installed!\n",
610 obj_desc));
611 return_ACPI_STATUS (status);
612 }
613
614 /*
615 * If the reference count on the object is more than one, we must
616 * take a copy of the object before we store. A reference count
617 * of exactly 1 means that the object was just created during the
618 * evaluation of an expression, and we can safely use it since it
619 * is not used anywhere else.
620 */
621 new_obj_desc = obj_desc;
622 if (obj_desc->common.reference_count > 1) {
623 status = acpi_ut_copy_iobject_to_iobject (obj_desc, &new_obj_desc, walk_state);
624 if (ACPI_FAILURE (status)) {
625 return_ACPI_STATUS (status);
626 }
627 }
628
629 /*
630 * If there is an object already in this slot, we either
631 * have to delete it, or if this is an argument and there
632 * is an object reference stored there, we have to do
633 * an indirect store!
634 */
635 if (current_obj_desc) {
636 /*
637 * Check for an indirect store if an argument
638 * contains an object reference (stored as an Node).
639 * We don't allow this automatic dereferencing for
640 * locals, since a store to a local should overwrite
641 * anything there, including an object reference.
642 *
643 * If both Arg0 and Local0 contain ref_of (Local4):
644 *
645 * Store (1, Arg0) - Causes indirect store to local4
646 * Store (1, Local0) - Stores 1 in local0, overwriting
647 * the reference to local4
648 * Store (1, de_refof (Local0)) - Causes indirect store to local4
649 *
650 * Weird, but true.
651 */
652 if (opcode == AML_ARG_OP) {
653 /*
654 * Make sure that the object is the correct type. This may be overkill, but
655 * it is here because references were NS nodes in the past. Now they are
656 * operand objects of type Reference.
657 */
658 if (ACPI_GET_DESCRIPTOR_TYPE (current_obj_desc) != ACPI_DESC_TYPE_OPERAND) {
659 ACPI_REPORT_ERROR (("Invalid descriptor type while storing to method arg: [%s]\n",
660 acpi_ut_get_descriptor_name (current_obj_desc)));
661 return_ACPI_STATUS (AE_AML_INTERNAL);
662 }
663
664 /*
665 * If we have a valid reference object that came from ref_of(), do the
666 * indirect store
667 */
668 if ((current_obj_desc->common.type == ACPI_TYPE_LOCAL_REFERENCE) &&
669 (current_obj_desc->reference.opcode == AML_REF_OF_OP)) {
670 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
671 "Arg (%p) is an obj_ref(Node), storing in node %p\n",
672 new_obj_desc, current_obj_desc));
673
674 /*
675 * Store this object to the Node (perform the indirect store)
676 * NOTE: No implicit conversion is performed, as per the ACPI
677 * specification rules on storing to Locals/Args.
678 */
679 status = acpi_ex_store_object_to_node (new_obj_desc,
680 current_obj_desc->reference.object, walk_state,
681 ACPI_NO_IMPLICIT_CONVERSION);
682
683 /* Remove local reference if we copied the object above */
684
685 if (new_obj_desc != obj_desc) {
686 acpi_ut_remove_reference (new_obj_desc);
687 }
688 return_ACPI_STATUS (status);
689 }
690 }
691
692 /*
693 * Delete the existing object
694 * before storing the new one
695 */
696 acpi_ds_method_data_delete_value (opcode, index, walk_state);
697 }
698
699 /*
700 * Install the Obj descriptor (*new_obj_desc) into
701 * the descriptor for the Arg or Local.
702 * (increments the object reference count by one)
703 */
704 status = acpi_ds_method_data_set_value (opcode, index, new_obj_desc, walk_state);
705
706 /* Remove local reference if we copied the object above */
707
708 if (new_obj_desc != obj_desc) {
709 acpi_ut_remove_reference (new_obj_desc);
710 }
711
712 return_ACPI_STATUS (status);
713}
714
715
diff --git a/drivers/acpi/dispatcher/dsobject.c b/drivers/acpi/dispatcher/dsobject.c
new file mode 100644
index 000000000000..eb8af4785bcb
--- /dev/null
+++ b/drivers/acpi/dispatcher/dsobject.c
@@ -0,0 +1,618 @@
1/******************************************************************************
2 *
3 * Module Name: dsobject - Dispatcher object management routines
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2005, R. Byron Moore
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
45#include <acpi/acpi.h>
46#include <acpi/acparser.h>
47#include <acpi/amlcode.h>
48#include <acpi/acdispat.h>
49#include <acpi/acnamesp.h>
50#include <acpi/acinterp.h>
51
52#define _COMPONENT ACPI_DISPATCHER
53 ACPI_MODULE_NAME ("dsobject")
54
55
56#ifndef ACPI_NO_METHOD_EXECUTION
57/*****************************************************************************
58 *
59 * FUNCTION: acpi_ds_build_internal_object
60 *
61 * PARAMETERS: walk_state - Current walk state
62 * Op - Parser object to be translated
63 * obj_desc_ptr - Where the ACPI internal object is returned
64 *
65 * RETURN: Status
66 *
67 * DESCRIPTION: Translate a parser Op object to the equivalent namespace object
68 * Simple objects are any objects other than a package object!
69 *
70 ****************************************************************************/
71
72acpi_status
73acpi_ds_build_internal_object (
74 struct acpi_walk_state *walk_state,
75 union acpi_parse_object *op,
76 union acpi_operand_object **obj_desc_ptr)
77{
78 union acpi_operand_object *obj_desc;
79 acpi_status status;
80
81
82 ACPI_FUNCTION_TRACE ("ds_build_internal_object");
83
84
85 *obj_desc_ptr = NULL;
86 if (op->common.aml_opcode == AML_INT_NAMEPATH_OP) {
87 /*
88 * This is an named object reference. If this name was
89 * previously looked up in the namespace, it was stored in this op.
90 * Otherwise, go ahead and look it up now
91 */
92 if (!op->common.node) {
93 status = acpi_ns_lookup (walk_state->scope_info, op->common.value.string,
94 ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
95 ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE, NULL,
96 (struct acpi_namespace_node **) &(op->common.node));
97
98 if (ACPI_FAILURE (status)) {
99 ACPI_REPORT_NSERROR (op->common.value.string, status);
100 return_ACPI_STATUS (status);
101 }
102 }
103 }
104
105 /* Create and init the internal ACPI object */
106
107 obj_desc = acpi_ut_create_internal_object ((acpi_ps_get_opcode_info (op->common.aml_opcode))->object_type);
108 if (!obj_desc) {
109 return_ACPI_STATUS (AE_NO_MEMORY);
110 }
111
112 status = acpi_ds_init_object_from_op (walk_state, op, op->common.aml_opcode, &obj_desc);
113 if (ACPI_FAILURE (status)) {
114 acpi_ut_remove_reference (obj_desc);
115 return_ACPI_STATUS (status);
116 }
117
118 *obj_desc_ptr = obj_desc;
119 return_ACPI_STATUS (AE_OK);
120}
121
122
123/*****************************************************************************
124 *
125 * FUNCTION: acpi_ds_build_internal_buffer_obj
126 *
127 * PARAMETERS: walk_state - Current walk state
128 * Op - Parser object to be translated
129 * buffer_length - Length of the buffer
130 * obj_desc_ptr - Where the ACPI internal object is returned
131 *
132 * RETURN: Status
133 *
134 * DESCRIPTION: Translate a parser Op package object to the equivalent
135 * namespace object
136 *
137 ****************************************************************************/
138
139acpi_status
140acpi_ds_build_internal_buffer_obj (
141 struct acpi_walk_state *walk_state,
142 union acpi_parse_object *op,
143 u32 buffer_length,
144 union acpi_operand_object **obj_desc_ptr)
145{
146 union acpi_parse_object *arg;
147 union acpi_operand_object *obj_desc;
148 union acpi_parse_object *byte_list;
149 u32 byte_list_length = 0;
150
151
152 ACPI_FUNCTION_TRACE ("ds_build_internal_buffer_obj");
153
154
155 obj_desc = *obj_desc_ptr;
156 if (obj_desc) {
157 /*
158 * We are evaluating a Named buffer object "Name (xxxx, Buffer)".
159 * The buffer object already exists (from the NS node)
160 */
161 }
162 else {
163 /* Create a new buffer object */
164
165 obj_desc = acpi_ut_create_internal_object (ACPI_TYPE_BUFFER);
166 *obj_desc_ptr = obj_desc;
167 if (!obj_desc) {
168 return_ACPI_STATUS (AE_NO_MEMORY);
169 }
170 }
171
172 /*
173 * Second arg is the buffer data (optional) byte_list can be either
174 * individual bytes or a string initializer. In either case, a
175 * byte_list appears in the AML.
176 */
177 arg = op->common.value.arg; /* skip first arg */
178
179 byte_list = arg->named.next;
180 if (byte_list) {
181 if (byte_list->common.aml_opcode != AML_INT_BYTELIST_OP) {
182 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
183 "Expecting bytelist, got AML opcode %X in op %p\n",
184 byte_list->common.aml_opcode, byte_list));
185
186 acpi_ut_remove_reference (obj_desc);
187 return (AE_TYPE);
188 }
189
190 byte_list_length = (u32) byte_list->common.value.integer;
191 }
192
193 /*
194 * The buffer length (number of bytes) will be the larger of:
195 * 1) The specified buffer length and
196 * 2) The length of the initializer byte list
197 */
198 obj_desc->buffer.length = buffer_length;
199 if (byte_list_length > buffer_length) {
200 obj_desc->buffer.length = byte_list_length;
201 }
202
203 /* Allocate the buffer */
204
205 if (obj_desc->buffer.length == 0) {
206 obj_desc->buffer.pointer = NULL;
207 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
208 "Buffer defined with zero length in AML, creating\n"));
209 }
210 else {
211 obj_desc->buffer.pointer = ACPI_MEM_CALLOCATE (
212 obj_desc->buffer.length);
213 if (!obj_desc->buffer.pointer) {
214 acpi_ut_delete_object_desc (obj_desc);
215 return_ACPI_STATUS (AE_NO_MEMORY);
216 }
217
218 /* Initialize buffer from the byte_list (if present) */
219
220 if (byte_list) {
221 ACPI_MEMCPY (obj_desc->buffer.pointer, byte_list->named.data,
222 byte_list_length);
223 }
224 }
225
226 obj_desc->buffer.flags |= AOPOBJ_DATA_VALID;
227 op->common.node = (struct acpi_namespace_node *) obj_desc;
228 return_ACPI_STATUS (AE_OK);
229}
230
231
232/*****************************************************************************
233 *
234 * FUNCTION: acpi_ds_build_internal_package_obj
235 *
236 * PARAMETERS: walk_state - Current walk state
237 * Op - Parser object to be translated
238 * package_length - Number of elements in the package
239 * obj_desc_ptr - Where the ACPI internal object is returned
240 *
241 * RETURN: Status
242 *
243 * DESCRIPTION: Translate a parser Op package object to the equivalent
244 * namespace object
245 *
246 ****************************************************************************/
247
248acpi_status
249acpi_ds_build_internal_package_obj (
250 struct acpi_walk_state *walk_state,
251 union acpi_parse_object *op,
252 u32 package_length,
253 union acpi_operand_object **obj_desc_ptr)
254{
255 union acpi_parse_object *arg;
256 union acpi_parse_object *parent;
257 union acpi_operand_object *obj_desc = NULL;
258 u32 package_list_length;
259 acpi_status status = AE_OK;
260 u32 i;
261
262
263 ACPI_FUNCTION_TRACE ("ds_build_internal_package_obj");
264
265
266 /* Find the parent of a possibly nested package */
267
268 parent = op->common.parent;
269 while ((parent->common.aml_opcode == AML_PACKAGE_OP) ||
270 (parent->common.aml_opcode == AML_VAR_PACKAGE_OP)) {
271 parent = parent->common.parent;
272 }
273
274 obj_desc = *obj_desc_ptr;
275 if (obj_desc) {
276 /*
277 * We are evaluating a Named package object "Name (xxxx, Package)".
278 * Get the existing package object from the NS node
279 */
280 }
281 else {
282 obj_desc = acpi_ut_create_internal_object (ACPI_TYPE_PACKAGE);
283 *obj_desc_ptr = obj_desc;
284 if (!obj_desc) {
285 return_ACPI_STATUS (AE_NO_MEMORY);
286 }
287
288 obj_desc->package.node = parent->common.node;
289 }
290
291 obj_desc->package.count = package_length;
292
293 /* Count the number of items in the package list */
294
295 package_list_length = 0;
296 arg = op->common.value.arg;
297 arg = arg->common.next;
298 while (arg) {
299 package_list_length++;
300 arg = arg->common.next;
301 }
302
303 /*
304 * The package length (number of elements) will be the greater
305 * of the specified length and the length of the initializer list
306 */
307 if (package_list_length > package_length) {
308 obj_desc->package.count = package_list_length;
309 }
310
311 /*
312 * Allocate the pointer array (array of pointers to the
313 * individual objects). Add an extra pointer slot so
314 * that the list is always null terminated.
315 */
316 obj_desc->package.elements = ACPI_MEM_CALLOCATE (
317 ((acpi_size) obj_desc->package.count + 1) * sizeof (void *));
318
319 if (!obj_desc->package.elements) {
320 acpi_ut_delete_object_desc (obj_desc);
321 return_ACPI_STATUS (AE_NO_MEMORY);
322 }
323
324 /*
325 * Now init the elements of the package
326 */
327 i = 0;
328 arg = op->common.value.arg;
329 arg = arg->common.next;
330 while (arg) {
331 if (arg->common.aml_opcode == AML_INT_RETURN_VALUE_OP) {
332 /* Object (package or buffer) is already built */
333
334 obj_desc->package.elements[i] = ACPI_CAST_PTR (union acpi_operand_object, arg->common.node);
335 }
336 else {
337 status = acpi_ds_build_internal_object (walk_state, arg,
338 &obj_desc->package.elements[i]);
339 }
340
341 i++;
342 arg = arg->common.next;
343 }
344
345 obj_desc->package.flags |= AOPOBJ_DATA_VALID;
346 op->common.node = (struct acpi_namespace_node *) obj_desc;
347 return_ACPI_STATUS (status);
348}
349
350
351/*****************************************************************************
352 *
353 * FUNCTION: acpi_ds_create_node
354 *
355 * PARAMETERS: walk_state - Current walk state
356 * Node - NS Node to be initialized
357 * Op - Parser object to be translated
358 *
359 * RETURN: Status
360 *
361 * DESCRIPTION: Create the object to be associated with a namespace node
362 *
363 ****************************************************************************/
364
365acpi_status
366acpi_ds_create_node (
367 struct acpi_walk_state *walk_state,
368 struct acpi_namespace_node *node,
369 union acpi_parse_object *op)
370{
371 acpi_status status;
372 union acpi_operand_object *obj_desc;
373
374
375 ACPI_FUNCTION_TRACE_PTR ("ds_create_node", op);
376
377
378 /*
379 * Because of the execution pass through the non-control-method
380 * parts of the table, we can arrive here twice. Only init
381 * the named object node the first time through
382 */
383 if (acpi_ns_get_attached_object (node)) {
384 return_ACPI_STATUS (AE_OK);
385 }
386
387 if (!op->common.value.arg) {
388 /* No arguments, there is nothing to do */
389
390 return_ACPI_STATUS (AE_OK);
391 }
392
393 /* Build an internal object for the argument(s) */
394
395 status = acpi_ds_build_internal_object (walk_state, op->common.value.arg, &obj_desc);
396 if (ACPI_FAILURE (status)) {
397 return_ACPI_STATUS (status);
398 }
399
400 /* Re-type the object according to its argument */
401
402 node->type = ACPI_GET_OBJECT_TYPE (obj_desc);
403
404 /* Attach obj to node */
405
406 status = acpi_ns_attach_object (node, obj_desc, node->type);
407
408 /* Remove local reference to the object */
409
410 acpi_ut_remove_reference (obj_desc);
411 return_ACPI_STATUS (status);
412}
413
414#endif /* ACPI_NO_METHOD_EXECUTION */
415
416
417/*****************************************************************************
418 *
419 * FUNCTION: acpi_ds_init_object_from_op
420 *
421 * PARAMETERS: walk_state - Current walk state
422 * Op - Parser op used to init the internal object
423 * Opcode - AML opcode associated with the object
424 * ret_obj_desc - Namespace object to be initialized
425 *
426 * RETURN: Status
427 *
428 * DESCRIPTION: Initialize a namespace object from a parser Op and its
429 * associated arguments. The namespace object is a more compact
430 * representation of the Op and its arguments.
431 *
432 ****************************************************************************/
433
434acpi_status
435acpi_ds_init_object_from_op (
436 struct acpi_walk_state *walk_state,
437 union acpi_parse_object *op,
438 u16 opcode,
439 union acpi_operand_object **ret_obj_desc)
440{
441 const struct acpi_opcode_info *op_info;
442 union acpi_operand_object *obj_desc;
443 acpi_status status = AE_OK;
444
445
446 ACPI_FUNCTION_TRACE ("ds_init_object_from_op");
447
448
449 obj_desc = *ret_obj_desc;
450 op_info = acpi_ps_get_opcode_info (opcode);
451 if (op_info->class == AML_CLASS_UNKNOWN) {
452 /* Unknown opcode */
453
454 return_ACPI_STATUS (AE_TYPE);
455 }
456
457 /* Perform per-object initialization */
458
459 switch (ACPI_GET_OBJECT_TYPE (obj_desc)) {
460 case ACPI_TYPE_BUFFER:
461
462 /*
463 * Defer evaluation of Buffer term_arg operand
464 */
465 obj_desc->buffer.node = (struct acpi_namespace_node *) walk_state->operands[0];
466 obj_desc->buffer.aml_start = op->named.data;
467 obj_desc->buffer.aml_length = op->named.length;
468 break;
469
470
471 case ACPI_TYPE_PACKAGE:
472
473 /*
474 * Defer evaluation of Package term_arg operand
475 */
476 obj_desc->package.node = (struct acpi_namespace_node *) walk_state->operands[0];
477 obj_desc->package.aml_start = op->named.data;
478 obj_desc->package.aml_length = op->named.length;
479 break;
480
481
482 case ACPI_TYPE_INTEGER:
483
484 switch (op_info->type) {
485 case AML_TYPE_CONSTANT:
486 /*
487 * Resolve AML Constants here - AND ONLY HERE!
488 * All constants are integers.
489 * We mark the integer with a flag that indicates that it started life
490 * as a constant -- so that stores to constants will perform as expected (noop).
491 * (zero_op is used as a placeholder for optional target operands.)
492 */
493 obj_desc->common.flags = AOPOBJ_AML_CONSTANT;
494
495 switch (opcode) {
496 case AML_ZERO_OP:
497
498 obj_desc->integer.value = 0;
499 break;
500
501 case AML_ONE_OP:
502
503 obj_desc->integer.value = 1;
504 break;
505
506 case AML_ONES_OP:
507
508 obj_desc->integer.value = ACPI_INTEGER_MAX;
509
510 /* Truncate value if we are executing from a 32-bit ACPI table */
511
512#ifndef ACPI_NO_METHOD_EXECUTION
513 acpi_ex_truncate_for32bit_table (obj_desc);
514#endif
515 break;
516
517 case AML_REVISION_OP:
518
519 obj_desc->integer.value = ACPI_CA_VERSION;
520 break;
521
522 default:
523
524 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown constant opcode %X\n", opcode));
525 status = AE_AML_OPERAND_TYPE;
526 break;
527 }
528 break;
529
530
531 case AML_TYPE_LITERAL:
532
533 obj_desc->integer.value = op->common.value.integer;
534 break;
535
536
537 default:
538 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown Integer type %X\n", op_info->type));
539 status = AE_AML_OPERAND_TYPE;
540 break;
541 }
542 break;
543
544
545 case ACPI_TYPE_STRING:
546
547 obj_desc->string.pointer = op->common.value.string;
548 obj_desc->string.length = (u32) ACPI_STRLEN (op->common.value.string);
549
550 /*
551 * The string is contained in the ACPI table, don't ever try
552 * to delete it
553 */
554 obj_desc->common.flags |= AOPOBJ_STATIC_POINTER;
555 break;
556
557
558 case ACPI_TYPE_METHOD:
559 break;
560
561
562 case ACPI_TYPE_LOCAL_REFERENCE:
563
564 switch (op_info->type) {
565 case AML_TYPE_LOCAL_VARIABLE:
566
567 /* Split the opcode into a base opcode + offset */
568
569 obj_desc->reference.opcode = AML_LOCAL_OP;
570 obj_desc->reference.offset = opcode - AML_LOCAL_OP;
571
572#ifndef ACPI_NO_METHOD_EXECUTION
573 status = acpi_ds_method_data_get_node (AML_LOCAL_OP, obj_desc->reference.offset,
574 walk_state, (struct acpi_namespace_node **) &obj_desc->reference.object);
575#endif
576 break;
577
578
579 case AML_TYPE_METHOD_ARGUMENT:
580
581 /* Split the opcode into a base opcode + offset */
582
583 obj_desc->reference.opcode = AML_ARG_OP;
584 obj_desc->reference.offset = opcode - AML_ARG_OP;
585
586#ifndef ACPI_NO_METHOD_EXECUTION
587 status = acpi_ds_method_data_get_node (AML_ARG_OP, obj_desc->reference.offset,
588 walk_state, (struct acpi_namespace_node **) &obj_desc->reference.object);
589#endif
590 break;
591
592 default: /* Other literals, etc.. */
593
594 if (op->common.aml_opcode == AML_INT_NAMEPATH_OP) {
595 /* Node was saved in Op */
596
597 obj_desc->reference.node = op->common.node;
598 }
599
600 obj_desc->reference.opcode = opcode;
601 break;
602 }
603 break;
604
605
606 default:
607
608 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unimplemented data type: %X\n",
609 ACPI_GET_OBJECT_TYPE (obj_desc)));
610
611 status = AE_AML_OPERAND_TYPE;
612 break;
613 }
614
615 return_ACPI_STATUS (status);
616}
617
618
diff --git a/drivers/acpi/dispatcher/dsopcode.c b/drivers/acpi/dispatcher/dsopcode.c
new file mode 100644
index 000000000000..5c987a0e7b75
--- /dev/null
+++ b/drivers/acpi/dispatcher/dsopcode.c
@@ -0,0 +1,1151 @@
1/******************************************************************************
2 *
3 * Module Name: dsopcode - Dispatcher Op Region support and handling of
4 * "control" opcodes
5 *
6 *****************************************************************************/
7
8/*
9 * Copyright (C) 2000 - 2005, R. Byron Moore
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
46#include <acpi/acpi.h>
47#include <acpi/acparser.h>
48#include <acpi/amlcode.h>
49#include <acpi/acdispat.h>
50#include <acpi/acinterp.h>
51#include <acpi/acnamesp.h>
52#include <acpi/acevents.h>
53
54#define _COMPONENT ACPI_DISPATCHER
55 ACPI_MODULE_NAME ("dsopcode")
56
57
58/*****************************************************************************
59 *
60 * FUNCTION: acpi_ds_execute_arguments
61 *
62 * PARAMETERS: Node - Parent NS node
63 * aml_length - Length of executable AML
64 * aml_start - Pointer to the AML
65 *
66 * RETURN: Status.
67 *
68 * DESCRIPTION: Late (deferred) execution of region or field arguments
69 *
70 ****************************************************************************/
71
72acpi_status
73acpi_ds_execute_arguments (
74 struct acpi_namespace_node *node,
75 struct acpi_namespace_node *scope_node,
76 u32 aml_length,
77 u8 *aml_start)
78{
79 acpi_status status;
80 union acpi_parse_object *op;
81 struct acpi_walk_state *walk_state;
82
83
84 ACPI_FUNCTION_TRACE ("ds_execute_arguments");
85
86
87 /*
88 * Allocate a new parser op to be the root of the parsed tree
89 */
90 op = acpi_ps_alloc_op (AML_INT_EVAL_SUBTREE_OP);
91 if (!op) {
92 return_ACPI_STATUS (AE_NO_MEMORY);
93 }
94
95 /* Save the Node for use in acpi_ps_parse_aml */
96
97 op->common.node = scope_node;
98
99 /* Create and initialize a new parser state */
100
101 walk_state = acpi_ds_create_walk_state (0, NULL, NULL, NULL);
102 if (!walk_state) {
103 return_ACPI_STATUS (AE_NO_MEMORY);
104 }
105
106 status = acpi_ds_init_aml_walk (walk_state, op, NULL, aml_start,
107 aml_length, NULL, 1);
108 if (ACPI_FAILURE (status)) {
109 acpi_ds_delete_walk_state (walk_state);
110 return_ACPI_STATUS (status);
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 acpi_ps_delete_parse_tree (op);
123 return_ACPI_STATUS (status);
124 }
125
126 /* Get and init the Op created above */
127
128 op->common.node = node;
129 acpi_ps_delete_parse_tree (op);
130
131 /* Evaluate the deferred arguments */
132
133 op = acpi_ps_alloc_op (AML_INT_EVAL_SUBTREE_OP);
134 if (!op) {
135 return_ACPI_STATUS (AE_NO_MEMORY);
136 }
137
138 op->common.node = scope_node;
139
140 /* Create and initialize a new parser state */
141
142 walk_state = acpi_ds_create_walk_state (0, NULL, NULL, NULL);
143 if (!walk_state) {
144 return_ACPI_STATUS (AE_NO_MEMORY);
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, 3);
151 if (ACPI_FAILURE (status)) {
152 acpi_ds_delete_walk_state (walk_state);
153 return_ACPI_STATUS (status);
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 acpi_ps_delete_parse_tree (op);
161 return_ACPI_STATUS (status);
162}
163
164
165/*****************************************************************************
166 *
167 * FUNCTION: acpi_ds_get_buffer_field_arguments
168 *
169 * PARAMETERS: obj_desc - A valid buffer_field object
170 *
171 * RETURN: Status.
172 *
173 * DESCRIPTION: Get buffer_field Buffer and Index. This implements the late
174 * evaluation of these field attributes.
175 *
176 ****************************************************************************/
177
178acpi_status
179acpi_ds_get_buffer_field_arguments (
180 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
187 ACPI_FUNCTION_TRACE_PTR ("ds_get_buffer_field_arguments", obj_desc);
188
189
190 if (obj_desc->common.flags & AOPOBJ_DATA_VALID) {
191 return_ACPI_STATUS (AE_OK);
192 }
193
194 /* Get the AML pointer (method object) and buffer_field node */
195
196 extra_desc = acpi_ns_get_secondary_object (obj_desc);
197 node = obj_desc->buffer_field.node;
198
199 ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname (ACPI_TYPE_BUFFER_FIELD, node, NULL));
200 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[%4.4s] buffer_field 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, acpi_ns_get_parent_node (node),
206 extra_desc->extra.aml_length, extra_desc->extra.aml_start);
207 return_ACPI_STATUS (status);
208}
209
210
211/*****************************************************************************
212 *
213 * FUNCTION: acpi_ds_get_buffer_arguments
214 *
215 * PARAMETERS: obj_desc - A valid Buffer object
216 *
217 * RETURN: Status.
218 *
219 * DESCRIPTION: Get Buffer length and initializer byte list. This implements
220 * the late evaluation of these attributes.
221 *
222 ****************************************************************************/
223
224acpi_status
225acpi_ds_get_buffer_arguments (
226 union acpi_operand_object *obj_desc)
227{
228 struct acpi_namespace_node *node;
229 acpi_status status;
230
231
232 ACPI_FUNCTION_TRACE_PTR ("ds_get_buffer_arguments", obj_desc);
233
234
235 if (obj_desc->common.flags & AOPOBJ_DATA_VALID) {
236 return_ACPI_STATUS (AE_OK);
237 }
238
239 /* Get the Buffer node */
240
241 node = obj_desc->buffer.node;
242 if (!node) {
243 ACPI_REPORT_ERROR ((
244 "No pointer back to NS node in buffer obj %p\n", obj_desc));
245 return_ACPI_STATUS (AE_AML_INTERNAL);
246 }
247
248 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Buffer Arg Init\n"));
249
250 /* Execute the AML code for the term_arg arguments */
251
252 status = acpi_ds_execute_arguments (node, node,
253 obj_desc->buffer.aml_length, obj_desc->buffer.aml_start);
254 return_ACPI_STATUS (status);
255}
256
257
258/*****************************************************************************
259 *
260 * FUNCTION: acpi_ds_get_package_arguments
261 *
262 * PARAMETERS: obj_desc - A valid Package object
263 *
264 * RETURN: Status.
265 *
266 * DESCRIPTION: Get Package length and initializer byte list. This implements
267 * the late evaluation of these attributes.
268 *
269 ****************************************************************************/
270
271acpi_status
272acpi_ds_get_package_arguments (
273 union acpi_operand_object *obj_desc)
274{
275 struct acpi_namespace_node *node;
276 acpi_status status;
277
278
279 ACPI_FUNCTION_TRACE_PTR ("ds_get_package_arguments", obj_desc);
280
281
282 if (obj_desc->common.flags & AOPOBJ_DATA_VALID) {
283 return_ACPI_STATUS (AE_OK);
284 }
285
286 /* Get the Package node */
287
288 node = obj_desc->package.node;
289 if (!node) {
290 ACPI_REPORT_ERROR ((
291 "No pointer back to NS node in package %p\n", obj_desc));
292 return_ACPI_STATUS (AE_AML_INTERNAL);
293 }
294
295 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Package Arg Init\n"));
296
297 /* Execute the AML code for the term_arg arguments */
298
299 status = acpi_ds_execute_arguments (node, node,
300 obj_desc->package.aml_length, obj_desc->package.aml_start);
301 return_ACPI_STATUS (status);
302}
303
304
305/*****************************************************************************
306 *
307 * FUNCTION: acpi_ds_get_region_arguments
308 *
309 * PARAMETERS: obj_desc - A valid region object
310 *
311 * RETURN: Status.
312 *
313 * DESCRIPTION: Get region address and length. This implements the late
314 * evaluation of these region attributes.
315 *
316 ****************************************************************************/
317
318acpi_status
319acpi_ds_get_region_arguments (
320 union acpi_operand_object *obj_desc)
321{
322 struct acpi_namespace_node *node;
323 acpi_status status;
324 union acpi_operand_object *extra_desc;
325
326
327 ACPI_FUNCTION_TRACE_PTR ("ds_get_region_arguments", obj_desc);
328
329
330 if (obj_desc->region.flags & AOPOBJ_DATA_VALID) {
331 return_ACPI_STATUS (AE_OK);
332 }
333
334 extra_desc = acpi_ns_get_secondary_object (obj_desc);
335 if (!extra_desc) {
336 return_ACPI_STATUS (AE_NOT_EXIST);
337 }
338
339 /* Get the Region node */
340
341 node = obj_desc->region.node;
342
343 ACPI_DEBUG_EXEC (acpi_ut_display_init_pathname (ACPI_TYPE_REGION, node, NULL));
344
345 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[%4.4s] op_region Arg Init at AML %p\n",
346 acpi_ut_get_node_name (node), extra_desc->extra.aml_start));
347
348 /* Execute the argument AML */
349
350 status = acpi_ds_execute_arguments (node, acpi_ns_get_parent_node (node),
351 extra_desc->extra.aml_length, extra_desc->extra.aml_start);
352 return_ACPI_STATUS (status);
353}
354
355
356/*****************************************************************************
357 *
358 * FUNCTION: acpi_ds_initialize_region
359 *
360 * PARAMETERS: Op - A valid region Op object
361 *
362 * RETURN: Status
363 *
364 * DESCRIPTION: Front end to ev_initialize_region
365 *
366 ****************************************************************************/
367
368acpi_status
369acpi_ds_initialize_region (
370 acpi_handle obj_handle)
371{
372 union acpi_operand_object *obj_desc;
373 acpi_status status;
374
375
376 obj_desc = acpi_ns_get_attached_object (obj_handle);
377
378 /* Namespace is NOT locked */
379
380 status = acpi_ev_initialize_region (obj_desc, FALSE);
381 return (status);
382}
383
384
385/*****************************************************************************
386 *
387 * FUNCTION: acpi_ds_init_buffer_field
388 *
389 * PARAMETERS: aml_opcode - create_xxx_field
390 * obj_desc - buffer_field object
391 * buffer_desc - Host Buffer
392 * offset_desc - Offset into buffer
393 * Length - Length of field (CREATE_FIELD_OP only)
394 * Result - Where to store the result
395 *
396 * RETURN: Status
397 *
398 * DESCRIPTION: Perform actual initialization of a buffer field
399 *
400 ****************************************************************************/
401
402acpi_status
403acpi_ds_init_buffer_field (
404 u16 aml_opcode,
405 union acpi_operand_object *obj_desc,
406 union acpi_operand_object *buffer_desc,
407 union acpi_operand_object *offset_desc,
408 union acpi_operand_object *length_desc,
409 union acpi_operand_object *result_desc)
410{
411 u32 offset;
412 u32 bit_offset;
413 u32 bit_count;
414 u8 field_flags;
415 acpi_status status;
416
417
418 ACPI_FUNCTION_TRACE_PTR ("ds_init_buffer_field", obj_desc);
419
420
421 /* Host object must be a Buffer */
422
423 if (ACPI_GET_OBJECT_TYPE (buffer_desc) != ACPI_TYPE_BUFFER) {
424 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
425 "Target of Create Field is not a Buffer object - %s\n",
426 acpi_ut_get_object_type_name (buffer_desc)));
427
428 status = AE_AML_OPERAND_TYPE;
429 goto cleanup;
430 }
431
432 /*
433 * The last parameter to all of these opcodes (result_desc) started
434 * out as a name_string, and should therefore now be a NS node
435 * after resolution in acpi_ex_resolve_operands().
436 */
437 if (ACPI_GET_DESCRIPTOR_TYPE (result_desc) != ACPI_DESC_TYPE_NAMED) {
438 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "(%s) destination not a NS Node [%s]\n",
439 acpi_ps_get_opcode_name (aml_opcode), acpi_ut_get_descriptor_name (result_desc)));
440
441 status = AE_AML_OPERAND_TYPE;
442 goto cleanup;
443 }
444
445 offset = (u32) offset_desc->integer.value;
446
447 /*
448 * Setup the Bit offsets and counts, according to the opcode
449 */
450 switch (aml_opcode) {
451 case AML_CREATE_FIELD_OP:
452
453 /* Offset is in bits, count is in bits */
454
455 bit_offset = offset;
456 bit_count = (u32) length_desc->integer.value;
457 field_flags = AML_FIELD_ACCESS_BYTE;
458 break;
459
460 case AML_CREATE_BIT_FIELD_OP:
461
462 /* Offset is in bits, Field is one bit */
463
464 bit_offset = offset;
465 bit_count = 1;
466 field_flags = AML_FIELD_ACCESS_BYTE;
467 break;
468
469 case AML_CREATE_BYTE_FIELD_OP:
470
471 /* Offset is in bytes, field is one byte */
472
473 bit_offset = 8 * offset;
474 bit_count = 8;
475 field_flags = AML_FIELD_ACCESS_BYTE;
476 break;
477
478 case AML_CREATE_WORD_FIELD_OP:
479
480 /* Offset is in bytes, field is one word */
481
482 bit_offset = 8 * offset;
483 bit_count = 16;
484 field_flags = AML_FIELD_ACCESS_WORD;
485 break;
486
487 case AML_CREATE_DWORD_FIELD_OP:
488
489 /* Offset is in bytes, field is one dword */
490
491 bit_offset = 8 * offset;
492 bit_count = 32;
493 field_flags = AML_FIELD_ACCESS_DWORD;
494 break;
495
496 case AML_CREATE_QWORD_FIELD_OP:
497
498 /* Offset is in bytes, field is one qword */
499
500 bit_offset = 8 * offset;
501 bit_count = 64;
502 field_flags = AML_FIELD_ACCESS_QWORD;
503 break;
504
505 default:
506
507 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
508 "Unknown field creation opcode %02x\n",
509 aml_opcode));
510 status = AE_AML_BAD_OPCODE;
511 goto cleanup;
512 }
513
514 /* Entire field must fit within the current length of the buffer */
515
516 if ((bit_offset + bit_count) >
517 (8 * (u32) buffer_desc->buffer.length)) {
518 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
519 "Field [%4.4s] size %d exceeds Buffer [%4.4s] size %d (bits)\n",
520 acpi_ut_get_node_name (result_desc),
521 bit_offset + bit_count,
522 acpi_ut_get_node_name (buffer_desc->buffer.node),
523 8 * (u32) buffer_desc->buffer.length));
524 status = AE_AML_BUFFER_LIMIT;
525 goto cleanup;
526 }
527
528 /*
529 * Initialize areas of the field object that are common to all fields
530 * For field_flags, use LOCK_RULE = 0 (NO_LOCK), UPDATE_RULE = 0 (UPDATE_PRESERVE)
531 */
532 status = acpi_ex_prep_common_field_object (obj_desc, field_flags, 0,
533 bit_offset, bit_count);
534 if (ACPI_FAILURE (status)) {
535 goto cleanup;
536 }
537
538 obj_desc->buffer_field.buffer_obj = buffer_desc;
539
540 /* Reference count for buffer_desc inherits obj_desc count */
541
542 buffer_desc->common.reference_count = (u16) (buffer_desc->common.reference_count +
543 obj_desc->common.reference_count);
544
545
546cleanup:
547
548 /* Always delete the operands */
549
550 acpi_ut_remove_reference (offset_desc);
551 acpi_ut_remove_reference (buffer_desc);
552
553 if (aml_opcode == AML_CREATE_FIELD_OP) {
554 acpi_ut_remove_reference (length_desc);
555 }
556
557 /* On failure, delete the result descriptor */
558
559 if (ACPI_FAILURE (status)) {
560 acpi_ut_remove_reference (result_desc); /* Result descriptor */
561 }
562 else {
563 /* Now the address and length are valid for this buffer_field */
564
565 obj_desc->buffer_field.flags |= AOPOBJ_DATA_VALID;
566 }
567
568 return_ACPI_STATUS (status);
569}
570
571
572/*****************************************************************************
573 *
574 * FUNCTION: acpi_ds_eval_buffer_field_operands
575 *
576 * PARAMETERS: walk_state - Current walk
577 * Op - A valid buffer_field Op object
578 *
579 * RETURN: Status
580 *
581 * DESCRIPTION: Get buffer_field Buffer and Index
582 * Called from acpi_ds_exec_end_op during buffer_field parse tree walk
583 *
584 ****************************************************************************/
585
586acpi_status
587acpi_ds_eval_buffer_field_operands (
588 struct acpi_walk_state *walk_state,
589 union acpi_parse_object *op)
590{
591 acpi_status status;
592 union acpi_operand_object *obj_desc;
593 struct acpi_namespace_node *node;
594 union acpi_parse_object *next_op;
595
596
597 ACPI_FUNCTION_TRACE_PTR ("ds_eval_buffer_field_operands", op);
598
599
600 /*
601 * This is where we evaluate the address and length fields of the
602 * create_xxx_field declaration
603 */
604 node = op->common.node;
605
606 /* next_op points to the op that holds the Buffer */
607
608 next_op = op->common.value.arg;
609
610 /* Evaluate/create the address and length operands */
611
612 status = acpi_ds_create_operands (walk_state, next_op);
613 if (ACPI_FAILURE (status)) {
614 return_ACPI_STATUS (status);
615 }
616
617 obj_desc = acpi_ns_get_attached_object (node);
618 if (!obj_desc) {
619 return_ACPI_STATUS (AE_NOT_EXIST);
620 }
621
622 /* Resolve the operands */
623
624 status = acpi_ex_resolve_operands (op->common.aml_opcode,
625 ACPI_WALK_OPERANDS, walk_state);
626
627 ACPI_DUMP_OPERANDS (ACPI_WALK_OPERANDS, ACPI_IMODE_EXECUTE,
628 acpi_ps_get_opcode_name (op->common.aml_opcode),
629 walk_state->num_operands, "after acpi_ex_resolve_operands");
630
631 if (ACPI_FAILURE (status)) {
632 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "(%s) bad operand(s) (%X)\n",
633 acpi_ps_get_opcode_name (op->common.aml_opcode), status));
634
635 return_ACPI_STATUS (status);
636 }
637
638 /* Initialize the Buffer Field */
639
640 if (op->common.aml_opcode == AML_CREATE_FIELD_OP) {
641 /* NOTE: Slightly different operands for this opcode */
642
643 status = acpi_ds_init_buffer_field (op->common.aml_opcode, obj_desc,
644 walk_state->operands[0], walk_state->operands[1],
645 walk_state->operands[2], walk_state->operands[3]);
646 }
647 else {
648 /* All other, create_xxx_field opcodes */
649
650 status = acpi_ds_init_buffer_field (op->common.aml_opcode, obj_desc,
651 walk_state->operands[0], walk_state->operands[1],
652 NULL, walk_state->operands[2]);
653 }
654
655 return_ACPI_STATUS (status);
656}
657
658
659/*****************************************************************************
660 *
661 * FUNCTION: acpi_ds_eval_region_operands
662 *
663 * PARAMETERS: walk_state - Current walk
664 * Op - A valid region Op object
665 *
666 * RETURN: Status
667 *
668 * DESCRIPTION: Get region address and length
669 * Called from acpi_ds_exec_end_op during op_region parse tree walk
670 *
671 ****************************************************************************/
672
673acpi_status
674acpi_ds_eval_region_operands (
675 struct acpi_walk_state *walk_state,
676 union acpi_parse_object *op)
677{
678 acpi_status status;
679 union acpi_operand_object *obj_desc;
680 union acpi_operand_object *operand_desc;
681 struct acpi_namespace_node *node;
682 union acpi_parse_object *next_op;
683
684
685 ACPI_FUNCTION_TRACE_PTR ("ds_eval_region_operands", op);
686
687
688 /*
689 * This is where we evaluate the address and length fields of the op_region declaration
690 */
691 node = op->common.node;
692
693 /* next_op points to the op that holds the space_iD */
694
695 next_op = op->common.value.arg;
696
697 /* next_op points to address op */
698
699 next_op = next_op->common.next;
700
701 /* Evaluate/create the address and length operands */
702
703 status = acpi_ds_create_operands (walk_state, next_op);
704 if (ACPI_FAILURE (status)) {
705 return_ACPI_STATUS (status);
706 }
707
708 /* Resolve the length and address operands to numbers */
709
710 status = acpi_ex_resolve_operands (op->common.aml_opcode, ACPI_WALK_OPERANDS, walk_state);
711 if (ACPI_FAILURE (status)) {
712 return_ACPI_STATUS (status);
713 }
714
715 ACPI_DUMP_OPERANDS (ACPI_WALK_OPERANDS, ACPI_IMODE_EXECUTE,
716 acpi_ps_get_opcode_name (op->common.aml_opcode),
717 1, "after acpi_ex_resolve_operands");
718
719 obj_desc = acpi_ns_get_attached_object (node);
720 if (!obj_desc) {
721 return_ACPI_STATUS (AE_NOT_EXIST);
722 }
723
724 /*
725 * Get the length operand and save it
726 * (at Top of stack)
727 */
728 operand_desc = walk_state->operands[walk_state->num_operands - 1];
729
730 obj_desc->region.length = (u32) operand_desc->integer.value;
731 acpi_ut_remove_reference (operand_desc);
732
733 /*
734 * Get the address and save it
735 * (at top of stack - 1)
736 */
737 operand_desc = walk_state->operands[walk_state->num_operands - 2];
738
739 obj_desc->region.address = (acpi_physical_address) operand_desc->integer.value;
740 acpi_ut_remove_reference (operand_desc);
741
742 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "rgn_obj %p Addr %8.8X%8.8X Len %X\n",
743 obj_desc,
744 ACPI_FORMAT_UINT64 (obj_desc->region.address),
745 obj_desc->region.length));
746
747 /* Now the address and length are valid for this opregion */
748
749 obj_desc->region.flags |= AOPOBJ_DATA_VALID;
750
751 return_ACPI_STATUS (status);
752}
753
754
755/*****************************************************************************
756 *
757 * FUNCTION: acpi_ds_eval_data_object_operands
758 *
759 * PARAMETERS: walk_state - Current walk
760 * Op - A valid data_object Op object
761 * obj_desc - data_object
762 *
763 * RETURN: Status
764 *
765 * DESCRIPTION: Get the operands and complete the following data object types:
766 * Buffer, Package.
767 *
768 ****************************************************************************/
769
770acpi_status
771acpi_ds_eval_data_object_operands (
772 struct acpi_walk_state *walk_state,
773 union acpi_parse_object *op,
774 union acpi_operand_object *obj_desc)
775{
776 acpi_status status;
777 union acpi_operand_object *arg_desc;
778 u32 length;
779
780
781 ACPI_FUNCTION_TRACE ("ds_eval_data_object_operands");
782
783
784 /* The first operand (for all of these data objects) is the length */
785
786 status = acpi_ds_create_operand (walk_state, op->common.value.arg, 1);
787 if (ACPI_FAILURE (status)) {
788 return_ACPI_STATUS (status);
789 }
790
791 status = acpi_ex_resolve_operands (walk_state->opcode,
792 &(walk_state->operands [walk_state->num_operands -1]),
793 walk_state);
794 if (ACPI_FAILURE (status)) {
795 return_ACPI_STATUS (status);
796 }
797
798 /* Extract length operand */
799
800 arg_desc = walk_state->operands [walk_state->num_operands - 1];
801 length = (u32) arg_desc->integer.value;
802
803 /* Cleanup for length operand */
804
805 status = acpi_ds_obj_stack_pop (1, walk_state);
806 if (ACPI_FAILURE (status)) {
807 return_ACPI_STATUS (status);
808 }
809
810 acpi_ut_remove_reference (arg_desc);
811
812 /*
813 * Create the actual data object
814 */
815 switch (op->common.aml_opcode) {
816 case AML_BUFFER_OP:
817
818 status = acpi_ds_build_internal_buffer_obj (walk_state, op, length, &obj_desc);
819 break;
820
821 case AML_PACKAGE_OP:
822 case AML_VAR_PACKAGE_OP:
823
824 status = acpi_ds_build_internal_package_obj (walk_state, op, length, &obj_desc);
825 break;
826
827 default:
828 return_ACPI_STATUS (AE_AML_BAD_OPCODE);
829 }
830
831 if (ACPI_SUCCESS (status)) {
832 /*
833 * Return the object in the walk_state, unless the parent is a package --
834 * in this case, the return object will be stored in the parse tree
835 * for the package.
836 */
837 if ((!op->common.parent) ||
838 ((op->common.parent->common.aml_opcode != AML_PACKAGE_OP) &&
839 (op->common.parent->common.aml_opcode != AML_VAR_PACKAGE_OP) &&
840 (op->common.parent->common.aml_opcode != AML_NAME_OP))) {
841 walk_state->result_obj = obj_desc;
842 }
843 }
844
845 return_ACPI_STATUS (status);
846}
847
848
849/*******************************************************************************
850 *
851 * FUNCTION: acpi_ds_exec_begin_control_op
852 *
853 * PARAMETERS: walk_list - The list that owns the walk stack
854 * Op - The control Op
855 *
856 * RETURN: Status
857 *
858 * DESCRIPTION: Handles all control ops encountered during control method
859 * execution.
860 *
861 ******************************************************************************/
862
863acpi_status
864acpi_ds_exec_begin_control_op (
865 struct acpi_walk_state *walk_state,
866 union acpi_parse_object *op)
867{
868 acpi_status status = AE_OK;
869 union acpi_generic_state *control_state;
870
871
872 ACPI_FUNCTION_NAME ("ds_exec_begin_control_op");
873
874
875 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Op=%p Opcode=%2.2X State=%p\n", op,
876 op->common.aml_opcode, walk_state));
877
878 switch (op->common.aml_opcode) {
879 case AML_IF_OP:
880 case AML_WHILE_OP:
881
882 /*
883 * IF/WHILE: Create a new control state to manage these
884 * constructs. We need to manage these as a stack, in order
885 * to handle nesting.
886 */
887 control_state = acpi_ut_create_control_state ();
888 if (!control_state) {
889 status = AE_NO_MEMORY;
890 break;
891 }
892 /*
893 * Save a pointer to the predicate for multiple executions
894 * of a loop
895 */
896 control_state->control.aml_predicate_start = walk_state->parser_state.aml - 1;
897 control_state->control.package_end = walk_state->parser_state.pkg_end;
898 control_state->control.opcode = op->common.aml_opcode;
899
900
901 /* Push the control state on this walk's control stack */
902
903 acpi_ut_push_generic_state (&walk_state->control_state, control_state);
904 break;
905
906 case AML_ELSE_OP:
907
908 /* Predicate is in the state object */
909 /* If predicate is true, the IF was executed, ignore ELSE part */
910
911 if (walk_state->last_predicate) {
912 status = AE_CTRL_TRUE;
913 }
914
915 break;
916
917 case AML_RETURN_OP:
918
919 break;
920
921 default:
922 break;
923 }
924
925 return (status);
926}
927
928
929/*******************************************************************************
930 *
931 * FUNCTION: acpi_ds_exec_end_control_op
932 *
933 * PARAMETERS: walk_list - The list that owns the walk stack
934 * Op - The control Op
935 *
936 * RETURN: Status
937 *
938 * DESCRIPTION: Handles all control ops encountered during control method
939 * execution.
940 *
941 ******************************************************************************/
942
943acpi_status
944acpi_ds_exec_end_control_op (
945 struct acpi_walk_state *walk_state,
946 union acpi_parse_object *op)
947{
948 acpi_status status = AE_OK;
949 union acpi_generic_state *control_state;
950
951
952 ACPI_FUNCTION_NAME ("ds_exec_end_control_op");
953
954
955 switch (op->common.aml_opcode) {
956 case AML_IF_OP:
957
958 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "[IF_OP] Op=%p\n", op));
959
960 /*
961 * Save the result of the predicate in case there is an
962 * ELSE to come
963 */
964 walk_state->last_predicate =
965 (u8) walk_state->control_state->common.value;
966
967 /*
968 * Pop the control state that was created at the start
969 * of the IF and free it
970 */
971 control_state = acpi_ut_pop_generic_state (&walk_state->control_state);
972 acpi_ut_delete_generic_state (control_state);
973 break;
974
975
976 case AML_ELSE_OP:
977
978 break;
979
980
981 case AML_WHILE_OP:
982
983 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "[WHILE_OP] Op=%p\n", op));
984
985 if (walk_state->control_state->common.value) {
986 /* Predicate was true, go back and evaluate it again! */
987
988 status = AE_CTRL_PENDING;
989 }
990
991 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "[WHILE_OP] termination! Op=%p\n", op));
992
993 /* Pop this control state and free it */
994
995 control_state = acpi_ut_pop_generic_state (&walk_state->control_state);
996
997 walk_state->aml_last_while = control_state->control.aml_predicate_start;
998 acpi_ut_delete_generic_state (control_state);
999 break;
1000
1001
1002 case AML_RETURN_OP:
1003
1004 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
1005 "[RETURN_OP] Op=%p Arg=%p\n",op, op->common.value.arg));
1006
1007 /*
1008 * One optional operand -- the return value
1009 * It can be either an immediate operand or a result that
1010 * has been bubbled up the tree
1011 */
1012 if (op->common.value.arg) {
1013 /* Since we have a real Return(), delete any implicit return */
1014
1015 acpi_ds_clear_implicit_return (walk_state);
1016
1017 /* Return statement has an immediate operand */
1018
1019 status = acpi_ds_create_operands (walk_state, op->common.value.arg);
1020 if (ACPI_FAILURE (status)) {
1021 return (status);
1022 }
1023
1024 /*
1025 * If value being returned is a Reference (such as
1026 * an arg or local), resolve it now because it may
1027 * cease to exist at the end of the method.
1028 */
1029 status = acpi_ex_resolve_to_value (&walk_state->operands [0], walk_state);
1030 if (ACPI_FAILURE (status)) {
1031 return (status);
1032 }
1033
1034 /*
1035 * Get the return value and save as the last result
1036 * value. This is the only place where walk_state->return_desc
1037 * is set to anything other than zero!
1038 */
1039 walk_state->return_desc = walk_state->operands[0];
1040 }
1041 else if ((walk_state->results) &&
1042 (walk_state->results->results.num_results > 0)) {
1043 /* Since we have a real Return(), delete any implicit return */
1044
1045 acpi_ds_clear_implicit_return (walk_state);
1046
1047 /*
1048 * The return value has come from a previous calculation.
1049 *
1050 * If value being returned is a Reference (such as
1051 * an arg or local), resolve it now because it may
1052 * cease to exist at the end of the method.
1053 *
1054 * Allow references created by the Index operator to return unchanged.
1055 */
1056 if ((ACPI_GET_DESCRIPTOR_TYPE (walk_state->results->results.obj_desc[0]) == ACPI_DESC_TYPE_OPERAND) &&
1057 (ACPI_GET_OBJECT_TYPE (walk_state->results->results.obj_desc [0]) == ACPI_TYPE_LOCAL_REFERENCE) &&
1058 ((walk_state->results->results.obj_desc [0])->reference.opcode != AML_INDEX_OP)) {
1059 status = acpi_ex_resolve_to_value (&walk_state->results->results.obj_desc [0], walk_state);
1060 if (ACPI_FAILURE (status)) {
1061 return (status);
1062 }
1063 }
1064
1065 walk_state->return_desc = walk_state->results->results.obj_desc [0];
1066 }
1067 else {
1068 /* No return operand */
1069
1070 if (walk_state->num_operands) {
1071 acpi_ut_remove_reference (walk_state->operands [0]);
1072 }
1073
1074 walk_state->operands [0] = NULL;
1075 walk_state->num_operands = 0;
1076 walk_state->return_desc = NULL;
1077 }
1078
1079
1080 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
1081 "Completed RETURN_OP State=%p, ret_val=%p\n",
1082 walk_state, walk_state->return_desc));
1083
1084 /* End the control method execution right now */
1085
1086 status = AE_CTRL_TERMINATE;
1087 break;
1088
1089
1090 case AML_NOOP_OP:
1091
1092 /* Just do nothing! */
1093 break;
1094
1095
1096 case AML_BREAK_POINT_OP:
1097
1098 /* Call up to the OS service layer to handle this */
1099
1100 status = acpi_os_signal (ACPI_SIGNAL_BREAKPOINT, "Executed AML Breakpoint opcode");
1101
1102 /* If and when it returns, all done. */
1103
1104 break;
1105
1106
1107 case AML_BREAK_OP:
1108 case AML_CONTINUE_OP: /* ACPI 2.0 */
1109
1110
1111 /* Pop and delete control states until we find a while */
1112
1113 while (walk_state->control_state &&
1114 (walk_state->control_state->control.opcode != AML_WHILE_OP)) {
1115 control_state = acpi_ut_pop_generic_state (&walk_state->control_state);
1116 acpi_ut_delete_generic_state (control_state);
1117 }
1118
1119 /* No while found? */
1120
1121 if (!walk_state->control_state) {
1122 return (AE_AML_NO_WHILE);
1123 }
1124
1125 /* Was: walk_state->aml_last_while = walk_state->control_state->Control.aml_predicate_start; */
1126
1127 walk_state->aml_last_while = walk_state->control_state->control.package_end;
1128
1129 /* Return status depending on opcode */
1130
1131 if (op->common.aml_opcode == AML_BREAK_OP) {
1132 status = AE_CTRL_BREAK;
1133 }
1134 else {
1135 status = AE_CTRL_CONTINUE;
1136 }
1137 break;
1138
1139
1140 default:
1141
1142 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown control opcode=%X Op=%p\n",
1143 op->common.aml_opcode, op));
1144
1145 status = AE_AML_BAD_OPCODE;
1146 break;
1147 }
1148
1149 return (status);
1150}
1151
diff --git a/drivers/acpi/dispatcher/dsutils.c b/drivers/acpi/dispatcher/dsutils.c
new file mode 100644
index 000000000000..462c5d83e747
--- /dev/null
+++ b/drivers/acpi/dispatcher/dsutils.c
@@ -0,0 +1,744 @@
1/*******************************************************************************
2 *
3 * Module Name: dsutils - Dispatcher utilities
4 *
5 ******************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2005, R. Byron Moore
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
45#include <acpi/acpi.h>
46#include <acpi/acparser.h>
47#include <acpi/amlcode.h>
48#include <acpi/acdispat.h>
49#include <acpi/acinterp.h>
50#include <acpi/acnamesp.h>
51#include <acpi/acdebug.h>
52
53#define _COMPONENT ACPI_DISPATCHER
54 ACPI_MODULE_NAME ("dsutils")
55
56
57/*******************************************************************************
58 *
59 * FUNCTION: acpi_ds_clear_implicit_return
60 *
61 * PARAMETERS: walk_state - Current State
62 *
63 * RETURN: None.
64 *
65 * DESCRIPTION: Clear and remove a reference on an implicit return value. Used
66 * to delete "stale" return values (if enabled, the return value
67 * from every operator is saved at least momentarily, in case the
68 * parent method exits.)
69 *
70 ******************************************************************************/
71
72void
73acpi_ds_clear_implicit_return (
74 struct acpi_walk_state *walk_state)
75{
76 ACPI_FUNCTION_NAME ("ds_clear_implicit_return");
77
78
79 /*
80 * Slack must be enabled for this feature
81 */
82 if (!acpi_gbl_enable_interpreter_slack) {
83 return;
84 }
85
86 if (walk_state->implicit_return_obj) {
87 /*
88 * Delete any "stale" implicit return. However, in
89 * complex statements, the implicit return value can be
90 * bubbled up several levels.
91 */
92 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
93 "Removing reference on stale implicit return obj %p\n",
94 walk_state->implicit_return_obj));
95
96 acpi_ut_remove_reference (walk_state->implicit_return_obj);
97 walk_state->implicit_return_obj = NULL;
98 }
99}
100
101
102#ifndef ACPI_NO_METHOD_EXECUTION
103
104/*******************************************************************************
105 *
106 * FUNCTION: acpi_ds_do_implicit_return
107 *
108 * PARAMETERS: return_desc - The return value
109 * walk_state - Current State
110 * add_reference - True if a reference should be added to the
111 * return object
112 *
113 * RETURN: TRUE if implicit return enabled, FALSE otherwise
114 *
115 * DESCRIPTION: Implements the optional "implicit return". We save the result
116 * of every ASL operator and control method invocation in case the
117 * parent method exit. Before storing a new return value, we
118 * delete the previous return value.
119 *
120 ******************************************************************************/
121
122u8
123acpi_ds_do_implicit_return (
124 union acpi_operand_object *return_desc,
125 struct acpi_walk_state *walk_state,
126 u8 add_reference)
127{
128 ACPI_FUNCTION_NAME ("ds_do_implicit_return");
129
130
131 /*
132 * Slack must be enabled for this feature, and we must
133 * have a valid return object
134 */
135 if ((!acpi_gbl_enable_interpreter_slack) ||
136 (!return_desc)) {
137 return (FALSE);
138 }
139
140 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
141 "Result %p will be implicitly returned; Prev=%p\n",
142 return_desc,
143 walk_state->implicit_return_obj));
144
145 /*
146 * Delete any "stale" implicit return value first. However, in
147 * complex statements, the implicit return value can be
148 * bubbled up several levels, so we don't clear the value if it
149 * is the same as the return_desc.
150 */
151 if (walk_state->implicit_return_obj) {
152 if (walk_state->implicit_return_obj == return_desc) {
153 return (TRUE);
154 }
155 acpi_ds_clear_implicit_return (walk_state);
156 }
157
158 /* Save the implicit return value, add a reference if requested */
159
160 walk_state->implicit_return_obj = return_desc;
161 if (add_reference) {
162 acpi_ut_add_reference (return_desc);
163 }
164
165 return (TRUE);
166}
167
168
169/*******************************************************************************
170 *
171 * FUNCTION: acpi_ds_is_result_used
172 *
173 * PARAMETERS: Op - Current Op
174 * walk_state - Current State
175 *
176 * RETURN: TRUE if result is used, FALSE otherwise
177 *
178 * DESCRIPTION: Check if a result object will be used by the parent
179 *
180 ******************************************************************************/
181
182u8
183acpi_ds_is_result_used (
184 union acpi_parse_object *op,
185 struct acpi_walk_state *walk_state)
186{
187 const struct acpi_opcode_info *parent_info;
188
189 ACPI_FUNCTION_TRACE_PTR ("ds_is_result_used", op);
190
191
192 /* Must have both an Op and a Result Object */
193
194 if (!op) {
195 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Null Op\n"));
196 return_VALUE (TRUE);
197 }
198
199 /*
200 * We know that this operator is not a
201 * Return() operator (would not come here.) The following code is the
202 * optional support for a so-called "implicit return". Some AML code
203 * assumes that the last value of the method is "implicitly" returned
204 * to the caller. Just save the last result as the return value.
205 * NOTE: this is optional because the ASL language does not actually
206 * support this behavior.
207 */
208 acpi_ds_do_implicit_return (walk_state->result_obj, walk_state, TRUE);
209
210 /*
211 * Now determine if the parent will use the result
212 *
213 * If there is no parent, or the parent is a scope_op, we are executing
214 * at the method level. An executing method typically has no parent,
215 * since each method is parsed separately. A method invoked externally
216 * via execute_control_method has a scope_op as the parent.
217 */
218 if ((!op->common.parent) ||
219 (op->common.parent->common.aml_opcode == AML_SCOPE_OP)) {
220 /* No parent, the return value cannot possibly be used */
221
222 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "At Method level, result of [%s] not used\n",
223 acpi_ps_get_opcode_name (op->common.aml_opcode)));
224 return_VALUE (FALSE);
225 }
226
227 /* Get info on the parent. The root_op is AML_SCOPE */
228
229 parent_info = acpi_ps_get_opcode_info (op->common.parent->common.aml_opcode);
230 if (parent_info->class == AML_CLASS_UNKNOWN) {
231 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown parent opcode. Op=%p\n", op));
232 return_VALUE (FALSE);
233 }
234
235 /*
236 * Decide what to do with the result based on the parent. If
237 * the parent opcode will not use the result, delete the object.
238 * Otherwise leave it as is, it will be deleted when it is used
239 * as an operand later.
240 */
241 switch (parent_info->class) {
242 case AML_CLASS_CONTROL:
243
244 switch (op->common.parent->common.aml_opcode) {
245 case AML_RETURN_OP:
246
247 /* Never delete the return value associated with a return opcode */
248
249 goto result_used;
250
251 case AML_IF_OP:
252 case AML_WHILE_OP:
253
254 /*
255 * If we are executing the predicate AND this is the predicate op,
256 * we will use the return value
257 */
258 if ((walk_state->control_state->common.state == ACPI_CONTROL_PREDICATE_EXECUTING) &&
259 (walk_state->control_state->control.predicate_op == op)) {
260 goto result_used;
261 }
262 break;
263
264 default:
265 /* Ignore other control opcodes */
266 break;
267 }
268
269 /* The general control opcode returns no result */
270
271 goto result_not_used;
272
273
274 case AML_CLASS_CREATE:
275
276 /*
277 * These opcodes allow term_arg(s) as operands and therefore
278 * the operands can be method calls. The result is used.
279 */
280 goto result_used;
281
282
283 case AML_CLASS_NAMED_OBJECT:
284
285 if ((op->common.parent->common.aml_opcode == AML_REGION_OP) ||
286 (op->common.parent->common.aml_opcode == AML_DATA_REGION_OP) ||
287 (op->common.parent->common.aml_opcode == AML_PACKAGE_OP) ||
288 (op->common.parent->common.aml_opcode == AML_VAR_PACKAGE_OP) ||
289 (op->common.parent->common.aml_opcode == AML_BUFFER_OP) ||
290 (op->common.parent->common.aml_opcode == AML_INT_EVAL_SUBTREE_OP)) {
291 /*
292 * These opcodes allow term_arg(s) as operands and therefore
293 * the operands can be method calls. The result is used.
294 */
295 goto result_used;
296 }
297
298 goto result_not_used;
299
300
301 default:
302
303 /*
304 * In all other cases. the parent will actually use the return
305 * object, so keep it.
306 */
307 goto result_used;
308 }
309
310
311result_used:
312 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Result of [%s] used by Parent [%s] Op=%p\n",
313 acpi_ps_get_opcode_name (op->common.aml_opcode),
314 acpi_ps_get_opcode_name (op->common.parent->common.aml_opcode), op));
315
316 return_VALUE (TRUE);
317
318
319result_not_used:
320 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Result of [%s] not used by Parent [%s] Op=%p\n",
321 acpi_ps_get_opcode_name (op->common.aml_opcode),
322 acpi_ps_get_opcode_name (op->common.parent->common.aml_opcode), op));
323
324 return_VALUE (FALSE);
325}
326
327
328/*******************************************************************************
329 *
330 * FUNCTION: acpi_ds_delete_result_if_not_used
331 *
332 * PARAMETERS: Op - Current parse Op
333 * result_obj - Result of the operation
334 * walk_state - Current state
335 *
336 * RETURN: Status
337 *
338 * DESCRIPTION: Used after interpretation of an opcode. If there is an internal
339 * result descriptor, check if the parent opcode will actually use
340 * this result. If not, delete the result now so that it will
341 * not become orphaned.
342 *
343 ******************************************************************************/
344
345void
346acpi_ds_delete_result_if_not_used (
347 union acpi_parse_object *op,
348 union acpi_operand_object *result_obj,
349 struct acpi_walk_state *walk_state)
350{
351 union acpi_operand_object *obj_desc;
352 acpi_status status;
353
354
355 ACPI_FUNCTION_TRACE_PTR ("ds_delete_result_if_not_used", result_obj);
356
357
358 if (!op) {
359 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Null Op\n"));
360 return_VOID;
361 }
362
363 if (!result_obj) {
364 return_VOID;
365 }
366
367 if (!acpi_ds_is_result_used (op, walk_state)) {
368 /* Must pop the result stack (obj_desc should be equal to result_obj) */
369
370 status = acpi_ds_result_pop (&obj_desc, walk_state);
371 if (ACPI_SUCCESS (status)) {
372 acpi_ut_remove_reference (result_obj);
373 }
374 }
375
376 return_VOID;
377}
378
379
380/*******************************************************************************
381 *
382 * FUNCTION: acpi_ds_resolve_operands
383 *
384 * PARAMETERS: walk_state - Current walk state with operands on stack
385 *
386 * RETURN: Status
387 *
388 * DESCRIPTION: Resolve all operands to their values. Used to prepare
389 * arguments to a control method invocation (a call from one
390 * method to another.)
391 *
392 ******************************************************************************/
393
394acpi_status
395acpi_ds_resolve_operands (
396 struct acpi_walk_state *walk_state)
397{
398 u32 i;
399 acpi_status status = AE_OK;
400
401
402 ACPI_FUNCTION_TRACE_PTR ("ds_resolve_operands", walk_state);
403
404
405 /*
406 * Attempt to resolve each of the valid operands
407 * Method arguments are passed by reference, not by value. This means
408 * that the actual objects are passed, not copies of the objects.
409 */
410 for (i = 0; i < walk_state->num_operands; i++) {
411 status = acpi_ex_resolve_to_value (&walk_state->operands[i], walk_state);
412 if (ACPI_FAILURE (status)) {
413 break;
414 }
415 }
416
417 return_ACPI_STATUS (status);
418}
419
420
421/*******************************************************************************
422 *
423 * FUNCTION: acpi_ds_clear_operands
424 *
425 * PARAMETERS: walk_state - Current walk state with operands on stack
426 *
427 * RETURN: None
428 *
429 * DESCRIPTION: Clear all operands on the current walk state operand stack.
430 *
431 ******************************************************************************/
432
433void
434acpi_ds_clear_operands (
435 struct acpi_walk_state *walk_state)
436{
437 u32 i;
438
439
440 ACPI_FUNCTION_TRACE_PTR ("ds_clear_operands", walk_state);
441
442
443 /* Remove a reference on each operand on the stack */
444
445 for (i = 0; i < walk_state->num_operands; i++) {
446 /*
447 * Remove a reference to all operands, including both
448 * "Arguments" and "Targets".
449 */
450 acpi_ut_remove_reference (walk_state->operands[i]);
451 walk_state->operands[i] = NULL;
452 }
453
454 walk_state->num_operands = 0;
455 return_VOID;
456}
457#endif
458
459
460/*******************************************************************************
461 *
462 * FUNCTION: acpi_ds_create_operand
463 *
464 * PARAMETERS: walk_state - Current walk state
465 * Arg - Parse object for the argument
466 * arg_index - Which argument (zero based)
467 *
468 * RETURN: Status
469 *
470 * DESCRIPTION: Translate a parse tree object that is an argument to an AML
471 * opcode to the equivalent interpreter object. This may include
472 * looking up a name or entering a new name into the internal
473 * namespace.
474 *
475 ******************************************************************************/
476
477acpi_status
478acpi_ds_create_operand (
479 struct acpi_walk_state *walk_state,
480 union acpi_parse_object *arg,
481 u32 arg_index)
482{
483 acpi_status status = AE_OK;
484 char *name_string;
485 u32 name_length;
486 union acpi_operand_object *obj_desc;
487 union acpi_parse_object *parent_op;
488 u16 opcode;
489 acpi_interpreter_mode interpreter_mode;
490 const struct acpi_opcode_info *op_info;
491
492
493 ACPI_FUNCTION_TRACE_PTR ("ds_create_operand", arg);
494
495
496 /* A valid name must be looked up in the namespace */
497
498 if ((arg->common.aml_opcode == AML_INT_NAMEPATH_OP) &&
499 (arg->common.value.string)) {
500 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Getting a name: Arg=%p\n", arg));
501
502 /* Get the entire name string from the AML stream */
503
504 status = acpi_ex_get_name_string (ACPI_TYPE_ANY, arg->common.value.buffer,
505 &name_string, &name_length);
506
507 if (ACPI_FAILURE (status)) {
508 return_ACPI_STATUS (status);
509 }
510
511 /* All prefixes have been handled, and the name is in name_string */
512
513 /*
514 * Special handling for buffer_field declarations. This is a deferred
515 * opcode that unfortunately defines the field name as the last
516 * parameter instead of the first. We get here when we are performing
517 * the deferred execution, so the actual name of the field is already
518 * in the namespace. We don't want to attempt to look it up again
519 * because we may be executing in a different scope than where the
520 * actual opcode exists.
521 */
522 if ((walk_state->deferred_node) &&
523 (walk_state->deferred_node->type == ACPI_TYPE_BUFFER_FIELD) &&
524 (arg_index != 0)) {
525 obj_desc = ACPI_CAST_PTR (union acpi_operand_object, walk_state->deferred_node);
526 status = AE_OK;
527 }
528 else /* All other opcodes */ {
529 /*
530 * Differentiate between a namespace "create" operation
531 * versus a "lookup" operation (IMODE_LOAD_PASS2 vs.
532 * IMODE_EXECUTE) in order to support the creation of
533 * namespace objects during the execution of control methods.
534 */
535 parent_op = arg->common.parent;
536 op_info = acpi_ps_get_opcode_info (parent_op->common.aml_opcode);
537 if ((op_info->flags & AML_NSNODE) &&
538 (parent_op->common.aml_opcode != AML_INT_METHODCALL_OP) &&
539 (parent_op->common.aml_opcode != AML_REGION_OP) &&
540 (parent_op->common.aml_opcode != AML_INT_NAMEPATH_OP)) {
541 /* Enter name into namespace if not found */
542
543 interpreter_mode = ACPI_IMODE_LOAD_PASS2;
544 }
545 else {
546 /* Return a failure if name not found */
547
548 interpreter_mode = ACPI_IMODE_EXECUTE;
549 }
550
551 status = acpi_ns_lookup (walk_state->scope_info, name_string,
552 ACPI_TYPE_ANY, interpreter_mode,
553 ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE,
554 walk_state,
555 ACPI_CAST_INDIRECT_PTR (struct acpi_namespace_node, &obj_desc));
556 /*
557 * The only case where we pass through (ignore) a NOT_FOUND
558 * error is for the cond_ref_of opcode.
559 */
560 if (status == AE_NOT_FOUND) {
561 if (parent_op->common.aml_opcode == AML_COND_REF_OF_OP) {
562 /*
563 * For the Conditional Reference op, it's OK if
564 * the name is not found; We just need a way to
565 * indicate this to the interpreter, set the
566 * object to the root
567 */
568 obj_desc = ACPI_CAST_PTR (union acpi_operand_object, acpi_gbl_root_node);
569 status = AE_OK;
570 }
571 else {
572 /*
573 * We just plain didn't find it -- which is a
574 * very serious error at this point
575 */
576 status = AE_AML_NAME_NOT_FOUND;
577 }
578 }
579
580 if (ACPI_FAILURE (status)) {
581 ACPI_REPORT_NSERROR (name_string, status);
582 }
583 }
584
585 /* Free the namestring created above */
586
587 ACPI_MEM_FREE (name_string);
588
589 /* Check status from the lookup */
590
591 if (ACPI_FAILURE (status)) {
592 return_ACPI_STATUS (status);
593 }
594
595 /* Put the resulting object onto the current object stack */
596
597 status = acpi_ds_obj_stack_push (obj_desc, walk_state);
598 if (ACPI_FAILURE (status)) {
599 return_ACPI_STATUS (status);
600 }
601 ACPI_DEBUGGER_EXEC (acpi_db_display_argument_object (obj_desc, walk_state));
602 }
603 else {
604 /* Check for null name case */
605
606 if (arg->common.aml_opcode == AML_INT_NAMEPATH_OP) {
607 /*
608 * If the name is null, this means that this is an
609 * optional result parameter that was not specified
610 * in the original ASL. Create a Zero Constant for a
611 * placeholder. (Store to a constant is a Noop.)
612 */
613 opcode = AML_ZERO_OP; /* Has no arguments! */
614
615 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Null namepath: Arg=%p\n", arg));
616 }
617 else {
618 opcode = arg->common.aml_opcode;
619 }
620
621 /* Get the object type of the argument */
622
623 op_info = acpi_ps_get_opcode_info (opcode);
624 if (op_info->object_type == ACPI_TYPE_INVALID) {
625 return_ACPI_STATUS (AE_NOT_IMPLEMENTED);
626 }
627
628 if (op_info->flags & AML_HAS_RETVAL) {
629 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
630 "Argument previously created, already stacked \n"));
631
632 ACPI_DEBUGGER_EXEC (acpi_db_display_argument_object (
633 walk_state->operands [walk_state->num_operands - 1], walk_state));
634
635 /*
636 * Use value that was already previously returned
637 * by the evaluation of this argument
638 */
639 status = acpi_ds_result_pop_from_bottom (&obj_desc, walk_state);
640 if (ACPI_FAILURE (status)) {
641 /*
642 * Only error is underflow, and this indicates
643 * a missing or null operand!
644 */
645 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Missing or null operand, %s\n",
646 acpi_format_exception (status)));
647 return_ACPI_STATUS (status);
648 }
649 }
650 else {
651 /* Create an ACPI_INTERNAL_OBJECT for the argument */
652
653 obj_desc = acpi_ut_create_internal_object (op_info->object_type);
654 if (!obj_desc) {
655 return_ACPI_STATUS (AE_NO_MEMORY);
656 }
657
658 /* Initialize the new object */
659
660 status = acpi_ds_init_object_from_op (walk_state, arg,
661 opcode, &obj_desc);
662 if (ACPI_FAILURE (status)) {
663 acpi_ut_delete_object_desc (obj_desc);
664 return_ACPI_STATUS (status);
665 }
666 }
667
668 /* Put the operand object on the object stack */
669
670 status = acpi_ds_obj_stack_push (obj_desc, walk_state);
671 if (ACPI_FAILURE (status)) {
672 return_ACPI_STATUS (status);
673 }
674
675 ACPI_DEBUGGER_EXEC (acpi_db_display_argument_object (obj_desc, walk_state));
676 }
677
678 return_ACPI_STATUS (AE_OK);
679}
680
681
682/*******************************************************************************
683 *
684 * FUNCTION: acpi_ds_create_operands
685 *
686 * PARAMETERS: walk_state - Current state
687 * first_arg - First argument of a parser argument tree
688 *
689 * RETURN: Status
690 *
691 * DESCRIPTION: Convert an operator's arguments from a parse tree format to
692 * namespace objects and place those argument object on the object
693 * stack in preparation for evaluation by the interpreter.
694 *
695 ******************************************************************************/
696
697acpi_status
698acpi_ds_create_operands (
699 struct acpi_walk_state *walk_state,
700 union acpi_parse_object *first_arg)
701{
702 acpi_status status = AE_OK;
703 union acpi_parse_object *arg;
704 u32 arg_count = 0;
705
706
707 ACPI_FUNCTION_TRACE_PTR ("ds_create_operands", first_arg);
708
709
710 /* For all arguments in the list... */
711
712 arg = first_arg;
713 while (arg) {
714 status = acpi_ds_create_operand (walk_state, arg, arg_count);
715 if (ACPI_FAILURE (status)) {
716 goto cleanup;
717 }
718
719 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Arg #%d (%p) done, Arg1=%p\n",
720 arg_count, arg, first_arg));
721
722 /* Move on to next argument, if any */
723
724 arg = arg->common.next;
725 arg_count++;
726 }
727
728 return_ACPI_STATUS (status);
729
730
731cleanup:
732 /*
733 * We must undo everything done above; meaning that we must
734 * pop everything off of the operand stack and delete those
735 * objects
736 */
737 (void) acpi_ds_obj_stack_pop_and_delete (arg_count, walk_state);
738
739 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "While creating Arg %d - %s\n",
740 (arg_count + 1), acpi_format_exception (status)));
741 return_ACPI_STATUS (status);
742}
743
744
diff --git a/drivers/acpi/dispatcher/dswexec.c b/drivers/acpi/dispatcher/dswexec.c
new file mode 100644
index 000000000000..2071a0d2bbbb
--- /dev/null
+++ b/drivers/acpi/dispatcher/dswexec.c
@@ -0,0 +1,751 @@
1/******************************************************************************
2 *
3 * Module Name: dswexec - Dispatcher method execution callbacks;
4 * dispatch to interpreter.
5 *
6 *****************************************************************************/
7
8/*
9 * Copyright (C) 2000 - 2005, R. Byron Moore
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
46#include <acpi/acpi.h>
47#include <acpi/acparser.h>
48#include <acpi/amlcode.h>
49#include <acpi/acdispat.h>
50#include <acpi/acinterp.h>
51#include <acpi/acnamesp.h>
52#include <acpi/acdebug.h>
53#include <acpi/acdisasm.h>
54
55
56#define _COMPONENT ACPI_DISPATCHER
57 ACPI_MODULE_NAME ("dswexec")
58
59/*
60 * Dispatch table for opcode classes
61 */
62static ACPI_EXECUTE_OP acpi_gbl_op_type_dispatch [] = {
63 acpi_ex_opcode_0A_0T_1R,
64 acpi_ex_opcode_1A_0T_0R,
65 acpi_ex_opcode_1A_0T_1R,
66 acpi_ex_opcode_1A_1T_0R,
67 acpi_ex_opcode_1A_1T_1R,
68 acpi_ex_opcode_2A_0T_0R,
69 acpi_ex_opcode_2A_0T_1R,
70 acpi_ex_opcode_2A_1T_1R,
71 acpi_ex_opcode_2A_2T_1R,
72 acpi_ex_opcode_3A_0T_0R,
73 acpi_ex_opcode_3A_1T_1R,
74 acpi_ex_opcode_6A_0T_1R};
75
76/*****************************************************************************
77 *
78 * FUNCTION: acpi_ds_get_predicate_value
79 *
80 * PARAMETERS: walk_state - Current state of the parse tree walk
81 *
82 * RETURN: Status
83 *
84 * DESCRIPTION: Get the result of a predicate evaluation
85 *
86 ****************************************************************************/
87
88acpi_status
89acpi_ds_get_predicate_value (
90 struct acpi_walk_state *walk_state,
91 union acpi_operand_object *result_obj) {
92 acpi_status status = AE_OK;
93 union acpi_operand_object *obj_desc;
94 union acpi_operand_object *local_obj_desc = NULL;
95
96
97 ACPI_FUNCTION_TRACE_PTR ("ds_get_predicate_value", walk_state);
98
99
100 walk_state->control_state->common.state = 0;
101
102 if (result_obj) {
103 status = acpi_ds_result_pop (&obj_desc, walk_state);
104 if (ACPI_FAILURE (status)) {
105 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
106 "Could not get result from predicate evaluation, %s\n",
107 acpi_format_exception (status)));
108
109 return_ACPI_STATUS (status);
110 }
111 }
112 else {
113 status = acpi_ds_create_operand (walk_state, walk_state->op, 0);
114 if (ACPI_FAILURE (status)) {
115 return_ACPI_STATUS (status);
116 }
117
118 status = acpi_ex_resolve_to_value (&walk_state->operands [0], walk_state);
119 if (ACPI_FAILURE (status)) {
120 return_ACPI_STATUS (status);
121 }
122
123 obj_desc = walk_state->operands [0];
124 }
125
126 if (!obj_desc) {
127 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "No predicate obj_desc=%p State=%p\n",
128 obj_desc, walk_state));
129
130 return_ACPI_STATUS (AE_AML_NO_OPERAND);
131 }
132
133 /*
134 * Result of predicate evaluation must be an Integer
135 * object. Implicitly convert the argument if necessary.
136 */
137 status = acpi_ex_convert_to_integer (obj_desc, &local_obj_desc, 16);
138 if (ACPI_FAILURE (status)) {
139 goto cleanup;
140 }
141
142 if (ACPI_GET_OBJECT_TYPE (local_obj_desc) != ACPI_TYPE_INTEGER) {
143 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
144 "Bad predicate (not an integer) obj_desc=%p State=%p Type=%X\n",
145 obj_desc, walk_state, ACPI_GET_OBJECT_TYPE (obj_desc)));
146
147 status = AE_AML_OPERAND_TYPE;
148 goto cleanup;
149 }
150
151 /* Truncate the predicate to 32-bits if necessary */
152
153 acpi_ex_truncate_for32bit_table (local_obj_desc);
154
155 /*
156 * Save the result of the predicate evaluation on
157 * the control stack
158 */
159 if (local_obj_desc->integer.value) {
160 walk_state->control_state->common.value = TRUE;
161 }
162 else {
163 /*
164 * Predicate is FALSE, we will just toss the
165 * rest of the package
166 */
167 walk_state->control_state->common.value = FALSE;
168 status = AE_CTRL_FALSE;
169 }
170
171
172cleanup:
173
174 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Completed a predicate eval=%X Op=%p\n",
175 walk_state->control_state->common.value, walk_state->op));
176
177 /* Break to debugger to display result */
178
179 ACPI_DEBUGGER_EXEC (acpi_db_display_result_object (local_obj_desc, walk_state));
180
181 /*
182 * Delete the predicate result object (we know that
183 * we don't need it anymore)
184 */
185 if (local_obj_desc != obj_desc) {
186 acpi_ut_remove_reference (local_obj_desc);
187 }
188 acpi_ut_remove_reference (obj_desc);
189
190 walk_state->control_state->common.state = ACPI_CONTROL_NORMAL;
191 return_ACPI_STATUS (status);
192}
193
194
195/*****************************************************************************
196 *
197 * FUNCTION: acpi_ds_exec_begin_op
198 *
199 * PARAMETERS: walk_state - Current state of the parse tree walk
200 * out_op - Return op if a new one is created
201 *
202 * RETURN: Status
203 *
204 * DESCRIPTION: Descending callback used during the execution of control
205 * methods. This is where most operators and operands are
206 * dispatched to the interpreter.
207 *
208 ****************************************************************************/
209
210acpi_status
211acpi_ds_exec_begin_op (
212 struct acpi_walk_state *walk_state,
213 union acpi_parse_object **out_op)
214{
215 union acpi_parse_object *op;
216 acpi_status status = AE_OK;
217 u32 opcode_class;
218
219
220 ACPI_FUNCTION_TRACE_PTR ("ds_exec_begin_op", walk_state);
221
222
223 op = walk_state->op;
224 if (!op) {
225 status = acpi_ds_load2_begin_op (walk_state, out_op);
226 if (ACPI_FAILURE (status)) {
227 return_ACPI_STATUS (status);
228 }
229
230 op = *out_op;
231 walk_state->op = op;
232 walk_state->opcode = op->common.aml_opcode;
233 walk_state->op_info = acpi_ps_get_opcode_info (op->common.aml_opcode);
234
235 if (acpi_ns_opens_scope (walk_state->op_info->object_type)) {
236 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "(%s) Popping scope for Op %p\n",
237 acpi_ut_get_type_name (walk_state->op_info->object_type), op));
238
239 status = acpi_ds_scope_stack_pop (walk_state);
240 if (ACPI_FAILURE (status)) {
241 return_ACPI_STATUS (status);
242 }
243 }
244 }
245
246 if (op == walk_state->origin) {
247 if (out_op) {
248 *out_op = op;
249 }
250
251 return_ACPI_STATUS (AE_OK);
252 }
253
254 /*
255 * If the previous opcode was a conditional, this opcode
256 * must be the beginning of the associated predicate.
257 * Save this knowledge in the current scope descriptor
258 */
259 if ((walk_state->control_state) &&
260 (walk_state->control_state->common.state ==
261 ACPI_CONTROL_CONDITIONAL_EXECUTING)) {
262 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Exec predicate Op=%p State=%p\n",
263 op, walk_state));
264
265 walk_state->control_state->common.state = ACPI_CONTROL_PREDICATE_EXECUTING;
266
267 /* Save start of predicate */
268
269 walk_state->control_state->control.predicate_op = op;
270 }
271
272
273 opcode_class = walk_state->op_info->class;
274
275 /* We want to send namepaths to the load code */
276
277 if (op->common.aml_opcode == AML_INT_NAMEPATH_OP) {
278 opcode_class = AML_CLASS_NAMED_OBJECT;
279 }
280
281 /*
282 * Handle the opcode based upon the opcode type
283 */
284 switch (opcode_class) {
285 case AML_CLASS_CONTROL:
286
287 status = acpi_ds_result_stack_push (walk_state);
288 if (ACPI_FAILURE (status)) {
289 return_ACPI_STATUS (status);
290 }
291
292 status = acpi_ds_exec_begin_control_op (walk_state, op);
293 break;
294
295
296 case AML_CLASS_NAMED_OBJECT:
297
298 if (walk_state->walk_type == ACPI_WALK_METHOD) {
299 /*
300 * Found a named object declaration during method
301 * execution; we must enter this object into the
302 * namespace. The created object is temporary and
303 * will be deleted upon completion of the execution
304 * of this method.
305 */
306 status = acpi_ds_load2_begin_op (walk_state, NULL);
307 }
308
309 if (op->common.aml_opcode == AML_REGION_OP) {
310 status = acpi_ds_result_stack_push (walk_state);
311 }
312 break;
313
314
315 case AML_CLASS_EXECUTE:
316 case AML_CLASS_CREATE:
317
318 /*
319 * Most operators with arguments.
320 * Start a new result/operand state
321 */
322 status = acpi_ds_result_stack_push (walk_state);
323 break;
324
325
326 default:
327 break;
328 }
329
330 /* Nothing to do here during method execution */
331
332 return_ACPI_STATUS (status);
333}
334
335
336/*****************************************************************************
337 *
338 * FUNCTION: acpi_ds_exec_end_op
339 *
340 * PARAMETERS: walk_state - Current state of the parse tree walk
341 * Op - Op that has been just been completed in the
342 * walk; Arguments have now been evaluated.
343 *
344 * RETURN: Status
345 *
346 * DESCRIPTION: Ascending callback used during the execution of control
347 * methods. The only thing we really need to do here is to
348 * notice the beginning of IF, ELSE, and WHILE blocks.
349 *
350 ****************************************************************************/
351
352acpi_status
353acpi_ds_exec_end_op (
354 struct acpi_walk_state *walk_state)
355{
356 union acpi_parse_object *op;
357 acpi_status status = AE_OK;
358 u32 op_type;
359 u32 op_class;
360 union acpi_parse_object *next_op;
361 union acpi_parse_object *first_arg;
362
363
364 ACPI_FUNCTION_TRACE_PTR ("ds_exec_end_op", walk_state);
365
366
367 op = walk_state->op;
368 op_type = walk_state->op_info->type;
369 op_class = walk_state->op_info->class;
370
371 if (op_class == AML_CLASS_UNKNOWN) {
372 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown opcode %X\n", op->common.aml_opcode));
373 return_ACPI_STATUS (AE_NOT_IMPLEMENTED);
374 }
375
376 first_arg = op->common.value.arg;
377
378 /* Init the walk state */
379
380 walk_state->num_operands = 0;
381 walk_state->return_desc = NULL;
382 walk_state->result_obj = NULL;
383
384 /* Call debugger for single step support (DEBUG build only) */
385
386 ACPI_DEBUGGER_EXEC (status = acpi_db_single_step (walk_state, op, op_class));
387 ACPI_DEBUGGER_EXEC (if (ACPI_FAILURE (status)) {return_ACPI_STATUS (status);});
388
389 /* Decode the Opcode Class */
390
391 switch (op_class) {
392 case AML_CLASS_ARGUMENT: /* constants, literals, etc. -- do nothing */
393 break;
394
395
396 case AML_CLASS_EXECUTE: /* most operators with arguments */
397
398 /* Build resolved operand stack */
399
400 status = acpi_ds_create_operands (walk_state, first_arg);
401 if (ACPI_FAILURE (status)) {
402 goto cleanup;
403 }
404
405 /* Done with this result state (Now that operand stack is built) */
406
407 status = acpi_ds_result_stack_pop (walk_state);
408 if (ACPI_FAILURE (status)) {
409 goto cleanup;
410 }
411
412 /*
413 * All opcodes require operand resolution, with the only exceptions
414 * being the object_type and size_of operators.
415 */
416 if (!(walk_state->op_info->flags & AML_NO_OPERAND_RESOLVE)) {
417 /* Resolve all operands */
418
419 status = acpi_ex_resolve_operands (walk_state->opcode,
420 &(walk_state->operands [walk_state->num_operands -1]),
421 walk_state);
422 if (ACPI_SUCCESS (status)) {
423 ACPI_DUMP_OPERANDS (ACPI_WALK_OPERANDS, ACPI_IMODE_EXECUTE,
424 acpi_ps_get_opcode_name (walk_state->opcode),
425 walk_state->num_operands, "after ex_resolve_operands");
426 }
427 }
428
429 if (ACPI_SUCCESS (status)) {
430 /*
431 * Dispatch the request to the appropriate interpreter handler
432 * routine. There is one routine per opcode "type" based upon the
433 * number of opcode arguments and return type.
434 */
435 status = acpi_gbl_op_type_dispatch[op_type] (walk_state);
436 }
437 else {
438 /*
439 * Treat constructs of the form "Store(local_x,local_x)" as noops when the
440 * Local is uninitialized.
441 */
442 if ((status == AE_AML_UNINITIALIZED_LOCAL) &&
443 (walk_state->opcode == AML_STORE_OP) &&
444 (walk_state->operands[0]->common.type == ACPI_TYPE_LOCAL_REFERENCE) &&
445 (walk_state->operands[1]->common.type == ACPI_TYPE_LOCAL_REFERENCE) &&
446 (walk_state->operands[0]->reference.opcode ==
447 walk_state->operands[1]->reference.opcode) &&
448 (walk_state->operands[0]->reference.offset ==
449 walk_state->operands[1]->reference.offset)) {
450 status = AE_OK;
451 }
452 else {
453 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
454 "[%s]: Could not resolve operands, %s\n",
455 acpi_ps_get_opcode_name (walk_state->opcode),
456 acpi_format_exception (status)));
457 }
458 }
459
460 /* Always delete the argument objects and clear the operand stack */
461
462 acpi_ds_clear_operands (walk_state);
463
464 /*
465 * If a result object was returned from above, push it on the
466 * current result stack
467 */
468 if (ACPI_SUCCESS (status) &&
469 walk_state->result_obj) {
470 status = acpi_ds_result_push (walk_state->result_obj, walk_state);
471 }
472
473 break;
474
475
476 default:
477
478 switch (op_type) {
479 case AML_TYPE_CONTROL: /* Type 1 opcode, IF/ELSE/WHILE/NOOP */
480
481 /* 1 Operand, 0 external_result, 0 internal_result */
482
483 status = acpi_ds_exec_end_control_op (walk_state, op);
484
485 /* Make sure to properly pop the result stack */
486
487 if (ACPI_SUCCESS (status)) {
488 status = acpi_ds_result_stack_pop (walk_state);
489 }
490 else if (status == AE_CTRL_PENDING) {
491 status = acpi_ds_result_stack_pop (walk_state);
492 if (ACPI_SUCCESS (status)) {
493 status = AE_CTRL_PENDING;
494 }
495 }
496 break;
497
498
499 case AML_TYPE_METHOD_CALL:
500
501 /*
502 * If the method is referenced from within a package
503 * declaration, it is not a invocation of the method, just
504 * a reference to it.
505 */
506 if ((op->asl.parent) &&
507 ((op->asl.parent->asl.aml_opcode == AML_PACKAGE_OP) ||
508 (op->asl.parent->asl.aml_opcode == AML_VAR_PACKAGE_OP))) {
509 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Method Reference in a Package, Op=%p\n", op));
510 op->common.node = (struct acpi_namespace_node *) op->asl.value.arg->asl.node->object;
511 acpi_ut_add_reference (op->asl.value.arg->asl.node->object);
512 return_ACPI_STATUS (AE_OK);
513 }
514
515 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Method invocation, Op=%p\n", op));
516
517 /*
518 * (AML_METHODCALL) Op->Asl.Value.Arg->Asl.Node contains
519 * the method Node pointer
520 */
521 /* next_op points to the op that holds the method name */
522
523 next_op = first_arg;
524
525 /* next_op points to first argument op */
526
527 next_op = next_op->common.next;
528
529 /*
530 * Get the method's arguments and put them on the operand stack
531 */
532 status = acpi_ds_create_operands (walk_state, next_op);
533 if (ACPI_FAILURE (status)) {
534 break;
535 }
536
537 /*
538 * Since the operands will be passed to another control method,
539 * we must resolve all local references here (Local variables,
540 * arguments to *this* method, etc.)
541 */
542 status = acpi_ds_resolve_operands (walk_state);
543 if (ACPI_FAILURE (status)) {
544 /* On error, clear all resolved operands */
545
546 acpi_ds_clear_operands (walk_state);
547 break;
548 }
549
550 /*
551 * Tell the walk loop to preempt this running method and
552 * execute the new method
553 */
554 status = AE_CTRL_TRANSFER;
555
556 /*
557 * Return now; we don't want to disturb anything,
558 * especially the operand count!
559 */
560 return_ACPI_STATUS (status);
561
562
563 case AML_TYPE_CREATE_FIELD:
564
565 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
566 "Executing create_field Buffer/Index Op=%p\n", op));
567
568 status = acpi_ds_load2_end_op (walk_state);
569 if (ACPI_FAILURE (status)) {
570 break;
571 }
572
573 status = acpi_ds_eval_buffer_field_operands (walk_state, op);
574 break;
575
576
577 case AML_TYPE_CREATE_OBJECT:
578
579 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
580 "Executing create_object (Buffer/Package) Op=%p\n", op));
581
582 switch (op->common.parent->common.aml_opcode) {
583 case AML_NAME_OP:
584
585 /*
586 * Put the Node on the object stack (Contains the ACPI Name of
587 * this object)
588 */
589 walk_state->operands[0] = (void *) op->common.parent->common.node;
590 walk_state->num_operands = 1;
591
592 status = acpi_ds_create_node (walk_state, op->common.parent->common.node, op->common.parent);
593 if (ACPI_FAILURE (status)) {
594 break;
595 }
596
597 /* Fall through */
598 /*lint -fallthrough */
599
600 case AML_INT_EVAL_SUBTREE_OP:
601
602 status = acpi_ds_eval_data_object_operands (walk_state, op,
603 acpi_ns_get_attached_object (op->common.parent->common.node));
604 break;
605
606 default:
607
608 status = acpi_ds_eval_data_object_operands (walk_state, op, NULL);
609 break;
610 }
611
612 /* Done with this result state (Now that operand stack is built) */
613
614 status = acpi_ds_result_stack_pop (walk_state);
615 if (ACPI_FAILURE (status)) {
616 goto cleanup;
617 }
618
619 /*
620 * If a result object was returned from above, push it on the
621 * current result stack
622 */
623 if (ACPI_SUCCESS (status) &&
624 walk_state->result_obj) {
625 status = acpi_ds_result_push (walk_state->result_obj, walk_state);
626 }
627 break;
628
629
630 case AML_TYPE_NAMED_FIELD:
631 case AML_TYPE_NAMED_COMPLEX:
632 case AML_TYPE_NAMED_SIMPLE:
633 case AML_TYPE_NAMED_NO_OBJ:
634
635 status = acpi_ds_load2_end_op (walk_state);
636 if (ACPI_FAILURE (status)) {
637 break;
638 }
639
640 if (op->common.aml_opcode == AML_REGION_OP) {
641 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
642 "Executing op_region Address/Length Op=%p\n", op));
643
644 status = acpi_ds_eval_region_operands (walk_state, op);
645 if (ACPI_FAILURE (status)) {
646 break;
647 }
648
649 status = acpi_ds_result_stack_pop (walk_state);
650 }
651
652 break;
653
654
655 case AML_TYPE_UNDEFINED:
656
657 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Undefined opcode type Op=%p\n", op));
658 return_ACPI_STATUS (AE_NOT_IMPLEMENTED);
659
660
661 case AML_TYPE_BOGUS:
662
663 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
664 "Internal opcode=%X type Op=%p\n",
665 walk_state->opcode, op));
666 break;
667
668
669 default:
670
671 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
672 "Unimplemented opcode, class=%X type=%X Opcode=%X Op=%p\n",
673 op_class, op_type, op->common.aml_opcode, op));
674
675 status = AE_NOT_IMPLEMENTED;
676 break;
677 }
678 }
679
680 /*
681 * ACPI 2.0 support for 64-bit integers: Truncate numeric
682 * result value if we are executing from a 32-bit ACPI table
683 */
684 acpi_ex_truncate_for32bit_table (walk_state->result_obj);
685
686 /*
687 * Check if we just completed the evaluation of a
688 * conditional predicate
689 */
690
691 if ((ACPI_SUCCESS (status)) &&
692 (walk_state->control_state) &&
693 (walk_state->control_state->common.state ==
694 ACPI_CONTROL_PREDICATE_EXECUTING) &&
695 (walk_state->control_state->control.predicate_op == op)) {
696 status = acpi_ds_get_predicate_value (walk_state, walk_state->result_obj);
697 walk_state->result_obj = NULL;
698 }
699
700
701cleanup:
702
703 /* Invoke exception handler on error */
704
705 if (ACPI_FAILURE (status) &&
706 acpi_gbl_exception_handler &&
707 !(status & AE_CODE_CONTROL)) {
708 acpi_ex_exit_interpreter ();
709 status = acpi_gbl_exception_handler (status,
710 walk_state->method_node->name.integer, walk_state->opcode,
711 walk_state->aml_offset, NULL);
712 acpi_ex_enter_interpreter ();
713 }
714
715 if (walk_state->result_obj) {
716 /* Break to debugger to display result */
717
718 ACPI_DEBUGGER_EXEC (acpi_db_display_result_object (walk_state->result_obj, walk_state));
719
720 /*
721 * Delete the result op if and only if:
722 * Parent will not use the result -- such as any
723 * non-nested type2 op in a method (parent will be method)
724 */
725 acpi_ds_delete_result_if_not_used (op, walk_state->result_obj, walk_state);
726 }
727
728#ifdef _UNDER_DEVELOPMENT
729
730 if (walk_state->parser_state.aml == walk_state->parser_state.aml_end) {
731 acpi_db_method_end (walk_state);
732 }
733#endif
734
735 /* Always clear the object stack */
736
737 walk_state->num_operands = 0;
738
739#ifdef ACPI_DISASSEMBLER
740
741 /* On error, display method locals/args */
742
743 if (ACPI_FAILURE (status)) {
744 acpi_dm_dump_method_info (status, walk_state, op);
745 }
746#endif
747
748 return_ACPI_STATUS (status);
749}
750
751
diff --git a/drivers/acpi/dispatcher/dswload.c b/drivers/acpi/dispatcher/dswload.c
new file mode 100644
index 000000000000..06d758679588
--- /dev/null
+++ b/drivers/acpi/dispatcher/dswload.c
@@ -0,0 +1,976 @@
1/******************************************************************************
2 *
3 * Module Name: dswload - Dispatcher namespace load callbacks
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2005, R. Byron Moore
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
45#include <acpi/acpi.h>
46#include <acpi/acparser.h>
47#include <acpi/amlcode.h>
48#include <acpi/acdispat.h>
49#include <acpi/acinterp.h>
50#include <acpi/acnamesp.h>
51#include <acpi/acevents.h>
52
53#ifdef _ACPI_ASL_COMPILER
54#include <acpi/acdisasm.h>
55#endif
56
57#define _COMPONENT ACPI_DISPATCHER
58 ACPI_MODULE_NAME ("dswload")
59
60
61/*******************************************************************************
62 *
63 * FUNCTION: acpi_ds_init_callbacks
64 *
65 * PARAMETERS: walk_state - Current state of the parse tree walk
66 * pass_number - 1, 2, or 3
67 *
68 * RETURN: Status
69 *
70 * DESCRIPTION: Init walk state callbacks
71 *
72 ******************************************************************************/
73
74acpi_status
75acpi_ds_init_callbacks (
76 struct acpi_walk_state *walk_state,
77 u32 pass_number)
78{
79
80 switch (pass_number) {
81 case 1:
82 walk_state->parse_flags = ACPI_PARSE_LOAD_PASS1 | ACPI_PARSE_DELETE_TREE;
83 walk_state->descending_callback = acpi_ds_load1_begin_op;
84 walk_state->ascending_callback = acpi_ds_load1_end_op;
85 break;
86
87 case 2:
88 walk_state->parse_flags = ACPI_PARSE_LOAD_PASS1 | ACPI_PARSE_DELETE_TREE;
89 walk_state->descending_callback = acpi_ds_load2_begin_op;
90 walk_state->ascending_callback = acpi_ds_load2_end_op;
91 break;
92
93 case 3:
94#ifndef ACPI_NO_METHOD_EXECUTION
95 walk_state->parse_flags |= ACPI_PARSE_EXECUTE | ACPI_PARSE_DELETE_TREE;
96 walk_state->descending_callback = acpi_ds_exec_begin_op;
97 walk_state->ascending_callback = acpi_ds_exec_end_op;
98#endif
99 break;
100
101 default:
102 return (AE_BAD_PARAMETER);
103 }
104
105 return (AE_OK);
106}
107
108
109/*******************************************************************************
110 *
111 * FUNCTION: acpi_ds_load1_begin_op
112 *
113 * PARAMETERS: walk_state - Current state of the parse tree walk
114 * Op - Op that has been just been reached in the
115 * walk; Arguments have not been evaluated yet.
116 *
117 * RETURN: Status
118 *
119 * DESCRIPTION: Descending callback used during the loading of ACPI tables.
120 *
121 ******************************************************************************/
122
123acpi_status
124acpi_ds_load1_begin_op (
125 struct acpi_walk_state *walk_state,
126 union acpi_parse_object **out_op)
127{
128 union acpi_parse_object *op;
129 struct acpi_namespace_node *node;
130 acpi_status status;
131 acpi_object_type object_type;
132 char *path;
133 u32 flags;
134
135
136 ACPI_FUNCTION_NAME ("ds_load1_begin_op");
137
138
139 op = walk_state->op;
140 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Op=%p State=%p\n", op, walk_state));
141
142 /* We are only interested in opcodes that have an associated name */
143
144 if (op) {
145 if (!(walk_state->op_info->flags & AML_NAMED)) {
146#if 0
147 if ((walk_state->op_info->class == AML_CLASS_EXECUTE) ||
148 (walk_state->op_info->class == AML_CLASS_CONTROL)) {
149 acpi_os_printf ("\n\n***EXECUTABLE OPCODE %s***\n\n", walk_state->op_info->name);
150 *out_op = op;
151 return (AE_CTRL_SKIP);
152 }
153#endif
154 *out_op = op;
155 return (AE_OK);
156 }
157
158 /* Check if this object has already been installed in the namespace */
159
160 if (op->common.node) {
161 *out_op = op;
162 return (AE_OK);
163 }
164 }
165
166 path = acpi_ps_get_next_namestring (&walk_state->parser_state);
167
168 /* Map the raw opcode into an internal object type */
169
170 object_type = walk_state->op_info->object_type;
171
172 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
173 "State=%p Op=%p [%s]\n", walk_state, op, acpi_ut_get_type_name (object_type)));
174
175 switch (walk_state->opcode) {
176 case AML_SCOPE_OP:
177
178 /*
179 * The target name of the Scope() operator must exist at this point so
180 * that we can actually open the scope to enter new names underneath it.
181 * Allow search-to-root for single namesegs.
182 */
183 status = acpi_ns_lookup (walk_state->scope_info, path, object_type,
184 ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT, walk_state, &(node));
185#ifdef _ACPI_ASL_COMPILER
186 if (status == AE_NOT_FOUND) {
187 /*
188 * Table disassembly:
189 * Target of Scope() not found. Generate an External for it, and
190 * insert the name into the namespace.
191 */
192 acpi_dm_add_to_external_list (path);
193 status = acpi_ns_lookup (walk_state->scope_info, path, object_type,
194 ACPI_IMODE_LOAD_PASS1, ACPI_NS_SEARCH_PARENT, walk_state, &(node));
195 }
196#endif
197 if (ACPI_FAILURE (status)) {
198 ACPI_REPORT_NSERROR (path, status);
199 return (status);
200 }
201
202 /*
203 * Check to make sure that the target is
204 * one of the opcodes that actually opens a scope
205 */
206 switch (node->type) {
207 case ACPI_TYPE_LOCAL_SCOPE: /* Scope */
208 case ACPI_TYPE_DEVICE:
209 case ACPI_TYPE_POWER:
210 case ACPI_TYPE_PROCESSOR:
211 case ACPI_TYPE_THERMAL:
212
213 /* These are acceptable types */
214 break;
215
216 case ACPI_TYPE_INTEGER:
217 case ACPI_TYPE_STRING:
218 case ACPI_TYPE_BUFFER:
219
220 /*
221 * These types we will allow, but we will change the type. This
222 * enables some existing code of the form:
223 *
224 * Name (DEB, 0)
225 * Scope (DEB) { ... }
226 *
227 * Note: silently change the type here. On the second pass, we will report a warning
228 */
229
230 ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Type override - [%4.4s] had invalid type (%s) for Scope operator, changed to (Scope)\n",
231 path, acpi_ut_get_type_name (node->type)));
232
233 node->type = ACPI_TYPE_ANY;
234 walk_state->scope_info->common.value = ACPI_TYPE_ANY;
235 break;
236
237 default:
238
239 /* All other types are an error */
240
241 ACPI_REPORT_ERROR (("Invalid type (%s) for target of Scope operator [%4.4s] (Cannot override)\n",
242 acpi_ut_get_type_name (node->type), path));
243
244 return (AE_AML_OPERAND_TYPE);
245 }
246 break;
247
248
249 default:
250
251 /*
252 * For all other named opcodes, we will enter the name into the namespace.
253 *
254 * Setup the search flags.
255 * Since we are entering a name into the namespace, we do not want to
256 * enable the search-to-root upsearch.
257 *
258 * There are only two conditions where it is acceptable that the name
259 * already exists:
260 * 1) the Scope() operator can reopen a scoping object that was
261 * previously defined (Scope, Method, Device, etc.)
262 * 2) Whenever we are parsing a deferred opcode (op_region, Buffer,
263 * buffer_field, or Package), the name of the object is already
264 * in the namespace.
265 */
266 if (walk_state->deferred_node) {
267 /* This name is already in the namespace, get the node */
268
269 node = walk_state->deferred_node;
270 status = AE_OK;
271 break;
272 }
273
274 flags = ACPI_NS_NO_UPSEARCH;
275 if ((walk_state->opcode != AML_SCOPE_OP) &&
276 (!(walk_state->parse_flags & ACPI_PARSE_DEFERRED_OP))) {
277 flags |= ACPI_NS_ERROR_IF_FOUND;
278 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "[%s] Cannot already exist\n",
279 acpi_ut_get_type_name (object_type)));
280 }
281 else {
282 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "[%s] Both Find or Create allowed\n",
283 acpi_ut_get_type_name (object_type)));
284 }
285
286 /*
287 * Enter the named type into the internal namespace. We enter the name
288 * as we go downward in the parse tree. Any necessary subobjects that involve
289 * arguments to the opcode must be created as we go back up the parse tree later.
290 */
291 status = acpi_ns_lookup (walk_state->scope_info, path, object_type,
292 ACPI_IMODE_LOAD_PASS1, flags, walk_state, &(node));
293 if (ACPI_FAILURE (status)) {
294 ACPI_REPORT_NSERROR (path, status);
295 return (status);
296 }
297 break;
298 }
299
300
301 /* Common exit */
302
303 if (!op) {
304 /* Create a new op */
305
306 op = acpi_ps_alloc_op (walk_state->opcode);
307 if (!op) {
308 return (AE_NO_MEMORY);
309 }
310 }
311
312 /* Initialize */
313
314 op->named.name = node->name.integer;
315
316#if (defined (ACPI_NO_METHOD_EXECUTION) || defined (ACPI_CONSTANT_EVAL_ONLY))
317 op->named.path = (u8 *) path;
318#endif
319
320
321 /*
322 * Put the Node in the "op" object that the parser uses, so we
323 * can get it again quickly when this scope is closed
324 */
325 op->common.node = node;
326 acpi_ps_append_arg (acpi_ps_get_parent_scope (&walk_state->parser_state), op);
327
328 *out_op = op;
329 return (status);
330}
331
332
333/*******************************************************************************
334 *
335 * FUNCTION: acpi_ds_load1_end_op
336 *
337 * PARAMETERS: walk_state - Current state of the parse tree walk
338 * Op - Op that has been just been completed in the
339 * walk; Arguments have now been evaluated.
340 *
341 * RETURN: Status
342 *
343 * DESCRIPTION: Ascending callback used during the loading of the namespace,
344 * both control methods and everything else.
345 *
346 ******************************************************************************/
347
348acpi_status
349acpi_ds_load1_end_op (
350 struct acpi_walk_state *walk_state)
351{
352 union acpi_parse_object *op;
353 acpi_object_type object_type;
354 acpi_status status = AE_OK;
355
356
357 ACPI_FUNCTION_NAME ("ds_load1_end_op");
358
359
360 op = walk_state->op;
361 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Op=%p State=%p\n", op, walk_state));
362
363 /* We are only interested in opcodes that have an associated name */
364
365 if (!(walk_state->op_info->flags & (AML_NAMED | AML_FIELD))) {
366 return (AE_OK);
367 }
368
369 /* Get the object type to determine if we should pop the scope */
370
371 object_type = walk_state->op_info->object_type;
372
373#ifndef ACPI_NO_METHOD_EXECUTION
374 if (walk_state->op_info->flags & AML_FIELD) {
375 if (walk_state->opcode == AML_FIELD_OP ||
376 walk_state->opcode == AML_BANK_FIELD_OP ||
377 walk_state->opcode == AML_INDEX_FIELD_OP) {
378 status = acpi_ds_init_field_objects (op, walk_state);
379 }
380 return (status);
381 }
382
383
384 if (op->common.aml_opcode == AML_REGION_OP) {
385 status = acpi_ex_create_region (op->named.data, op->named.length,
386 (acpi_adr_space_type) ((op->common.value.arg)->common.value.integer), walk_state);
387 if (ACPI_FAILURE (status)) {
388 return (status);
389 }
390 }
391#endif
392
393 if (op->common.aml_opcode == AML_NAME_OP) {
394 /* For Name opcode, get the object type from the argument */
395
396 if (op->common.value.arg) {
397 object_type = (acpi_ps_get_opcode_info ((op->common.value.arg)->common.aml_opcode))->object_type;
398 op->common.node->type = (u8) object_type;
399 }
400 }
401
402 if (op->common.aml_opcode == AML_METHOD_OP) {
403 /*
404 * method_op pkg_length name_string method_flags term_list
405 *
406 * Note: We must create the method node/object pair as soon as we
407 * see the method declaration. This allows later pass1 parsing
408 * of invocations of the method (need to know the number of
409 * arguments.)
410 */
411 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
412 "LOADING-Method: State=%p Op=%p named_obj=%p\n",
413 walk_state, op, op->named.node));
414
415 if (!acpi_ns_get_attached_object (op->named.node)) {
416 walk_state->operands[0] = (void *) op->named.node;
417 walk_state->num_operands = 1;
418
419 status = acpi_ds_create_operands (walk_state, op->common.value.arg);
420 if (ACPI_SUCCESS (status)) {
421 status = acpi_ex_create_method (op->named.data,
422 op->named.length, walk_state);
423 }
424 walk_state->operands[0] = NULL;
425 walk_state->num_operands = 0;
426
427 if (ACPI_FAILURE (status)) {
428 return (status);
429 }
430 }
431 }
432
433 /* Pop the scope stack */
434
435 if (acpi_ns_opens_scope (object_type)) {
436 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "(%s): Popping scope for Op %p\n",
437 acpi_ut_get_type_name (object_type), op));
438
439 status = acpi_ds_scope_stack_pop (walk_state);
440 }
441
442 return (status);
443}
444
445
446/*******************************************************************************
447 *
448 * FUNCTION: acpi_ds_load2_begin_op
449 *
450 * PARAMETERS: walk_state - Current state of the parse tree walk
451 * Op - Op that has been just been reached in the
452 * walk; Arguments have not been evaluated yet.
453 *
454 * RETURN: Status
455 *
456 * DESCRIPTION: Descending callback used during the loading of ACPI tables.
457 *
458 ******************************************************************************/
459
460acpi_status
461acpi_ds_load2_begin_op (
462 struct acpi_walk_state *walk_state,
463 union acpi_parse_object **out_op)
464{
465 union acpi_parse_object *op;
466 struct acpi_namespace_node *node;
467 acpi_status status;
468 acpi_object_type object_type;
469 char *buffer_ptr;
470
471
472 ACPI_FUNCTION_TRACE ("ds_load2_begin_op");
473
474
475 op = walk_state->op;
476 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Op=%p State=%p\n", op, walk_state));
477
478 if (op) {
479 /* We only care about Namespace opcodes here */
480
481 if ((!(walk_state->op_info->flags & AML_NSOPCODE) && (walk_state->opcode != AML_INT_NAMEPATH_OP)) ||
482 (!(walk_state->op_info->flags & AML_NAMED))) {
483 return_ACPI_STATUS (AE_OK);
484 }
485
486 /*
487 * Get the name we are going to enter or lookup in the namespace
488 */
489 if (walk_state->opcode == AML_INT_NAMEPATH_OP) {
490 /* For Namepath op, get the path string */
491
492 buffer_ptr = op->common.value.string;
493 if (!buffer_ptr) {
494 /* No name, just exit */
495
496 return_ACPI_STATUS (AE_OK);
497 }
498 }
499 else {
500 /* Get name from the op */
501
502 buffer_ptr = (char *) &op->named.name;
503 }
504 }
505 else {
506 /* Get the namestring from the raw AML */
507
508 buffer_ptr = acpi_ps_get_next_namestring (&walk_state->parser_state);
509 }
510
511 /* Map the opcode into an internal object type */
512
513 object_type = walk_state->op_info->object_type;
514
515 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
516 "State=%p Op=%p Type=%X\n", walk_state, op, object_type));
517
518
519 switch (walk_state->opcode) {
520 case AML_FIELD_OP:
521 case AML_BANK_FIELD_OP:
522 case AML_INDEX_FIELD_OP:
523
524 node = NULL;
525 status = AE_OK;
526 break;
527
528 case AML_INT_NAMEPATH_OP:
529
530 /*
531 * The name_path is an object reference to an existing object. Don't enter the
532 * name into the namespace, but look it up for use later
533 */
534 status = acpi_ns_lookup (walk_state->scope_info, buffer_ptr, object_type,
535 ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT, walk_state, &(node));
536 break;
537
538 case AML_SCOPE_OP:
539
540 /*
541 * The Path is an object reference to an existing object. Don't enter the
542 * name into the namespace, but look it up for use later
543 */
544 status = acpi_ns_lookup (walk_state->scope_info, buffer_ptr, object_type,
545 ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT, walk_state, &(node));
546 if (ACPI_FAILURE (status)) {
547#ifdef _ACPI_ASL_COMPILER
548 if (status == AE_NOT_FOUND) {
549 status = AE_OK;
550 }
551 else {
552 ACPI_REPORT_NSERROR (buffer_ptr, status);
553 }
554#else
555 ACPI_REPORT_NSERROR (buffer_ptr, status);
556#endif
557 return_ACPI_STATUS (status);
558 }
559 /*
560 * We must check to make sure that the target is
561 * one of the opcodes that actually opens a scope
562 */
563 switch (node->type) {
564 case ACPI_TYPE_LOCAL_SCOPE: /* Scope */
565 case ACPI_TYPE_DEVICE:
566 case ACPI_TYPE_POWER:
567 case ACPI_TYPE_PROCESSOR:
568 case ACPI_TYPE_THERMAL:
569
570 /* These are acceptable types */
571 break;
572
573 case ACPI_TYPE_INTEGER:
574 case ACPI_TYPE_STRING:
575 case ACPI_TYPE_BUFFER:
576
577 /*
578 * These types we will allow, but we will change the type. This
579 * enables some existing code of the form:
580 *
581 * Name (DEB, 0)
582 * Scope (DEB) { ... }
583 */
584
585 ACPI_REPORT_WARNING (("Type override - [%4.4s] had invalid type (%s) for Scope operator, changed to (Scope)\n",
586 buffer_ptr, acpi_ut_get_type_name (node->type)));
587
588 node->type = ACPI_TYPE_ANY;
589 walk_state->scope_info->common.value = ACPI_TYPE_ANY;
590 break;
591
592 default:
593
594 /* All other types are an error */
595
596 ACPI_REPORT_ERROR (("Invalid type (%s) for target of Scope operator [%4.4s]\n",
597 acpi_ut_get_type_name (node->type), buffer_ptr));
598
599 return (AE_AML_OPERAND_TYPE);
600 }
601 break;
602
603 default:
604
605 /* All other opcodes */
606
607 if (op && op->common.node) {
608 /* This op/node was previously entered into the namespace */
609
610 node = op->common.node;
611
612 if (acpi_ns_opens_scope (object_type)) {
613 status = acpi_ds_scope_stack_push (node, object_type, walk_state);
614 if (ACPI_FAILURE (status)) {
615 return_ACPI_STATUS (status);
616 }
617
618 }
619 return_ACPI_STATUS (AE_OK);
620 }
621
622 /*
623 * Enter the named type into the internal namespace. We enter the name
624 * as we go downward in the parse tree. Any necessary subobjects that involve
625 * arguments to the opcode must be created as we go back up the parse tree later.
626 *
627 * Note: Name may already exist if we are executing a deferred opcode.
628 */
629 if (walk_state->deferred_node) {
630 /* This name is already in the namespace, get the node */
631
632 node = walk_state->deferred_node;
633 status = AE_OK;
634 break;
635 }
636
637 status = acpi_ns_lookup (walk_state->scope_info, buffer_ptr, object_type,
638 ACPI_IMODE_EXECUTE, ACPI_NS_NO_UPSEARCH, walk_state, &(node));
639 break;
640 }
641
642 if (ACPI_FAILURE (status)) {
643 ACPI_REPORT_NSERROR (buffer_ptr, status);
644 return_ACPI_STATUS (status);
645 }
646
647
648 if (!op) {
649 /* Create a new op */
650
651 op = acpi_ps_alloc_op (walk_state->opcode);
652 if (!op) {
653 return_ACPI_STATUS (AE_NO_MEMORY);
654 }
655
656 /* Initialize the new op */
657
658 if (node) {
659 op->named.name = node->name.integer;
660 }
661 if (out_op) {
662 *out_op = op;
663 }
664 }
665
666 /*
667 * Put the Node in the "op" object that the parser uses, so we
668 * can get it again quickly when this scope is closed
669 */
670 op->common.node = node;
671
672 return_ACPI_STATUS (status);
673}
674
675
676/*******************************************************************************
677 *
678 * FUNCTION: acpi_ds_load2_end_op
679 *
680 * PARAMETERS: walk_state - Current state of the parse tree walk
681 * Op - Op that has been just been completed in the
682 * walk; Arguments have now been evaluated.
683 *
684 * RETURN: Status
685 *
686 * DESCRIPTION: Ascending callback used during the loading of the namespace,
687 * both control methods and everything else.
688 *
689 ******************************************************************************/
690
691acpi_status
692acpi_ds_load2_end_op (
693 struct acpi_walk_state *walk_state)
694{
695 union acpi_parse_object *op;
696 acpi_status status = AE_OK;
697 acpi_object_type object_type;
698 struct acpi_namespace_node *node;
699 union acpi_parse_object *arg;
700 struct acpi_namespace_node *new_node;
701#ifndef ACPI_NO_METHOD_EXECUTION
702 u32 i;
703#endif
704
705
706 ACPI_FUNCTION_TRACE ("ds_load2_end_op");
707
708 op = walk_state->op;
709 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Opcode [%s] Op %p State %p\n",
710 walk_state->op_info->name, op, walk_state));
711
712 /* Only interested in opcodes that have namespace objects */
713
714 if (!(walk_state->op_info->flags & AML_NSOBJECT)) {
715 return_ACPI_STATUS (AE_OK);
716 }
717
718 if (op->common.aml_opcode == AML_SCOPE_OP) {
719 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
720 "Ending scope Op=%p State=%p\n", op, walk_state));
721 }
722
723
724 object_type = walk_state->op_info->object_type;
725
726 /*
727 * Get the Node/name from the earlier lookup
728 * (It was saved in the *op structure)
729 */
730 node = op->common.node;
731
732 /*
733 * Put the Node on the object stack (Contains the ACPI Name of
734 * this object)
735 */
736 walk_state->operands[0] = (void *) node;
737 walk_state->num_operands = 1;
738
739 /* Pop the scope stack */
740
741 if (acpi_ns_opens_scope (object_type) && (op->common.aml_opcode != AML_INT_METHODCALL_OP)) {
742 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "(%s) Popping scope for Op %p\n",
743 acpi_ut_get_type_name (object_type), op));
744
745 status = acpi_ds_scope_stack_pop (walk_state);
746 if (ACPI_FAILURE (status)) {
747 goto cleanup;
748 }
749 }
750
751 /*
752 * Named operations are as follows:
753 *
754 * AML_ALIAS
755 * AML_BANKFIELD
756 * AML_CREATEBITFIELD
757 * AML_CREATEBYTEFIELD
758 * AML_CREATEDWORDFIELD
759 * AML_CREATEFIELD
760 * AML_CREATEQWORDFIELD
761 * AML_CREATEWORDFIELD
762 * AML_DATA_REGION
763 * AML_DEVICE
764 * AML_EVENT
765 * AML_FIELD
766 * AML_INDEXFIELD
767 * AML_METHOD
768 * AML_METHODCALL
769 * AML_MUTEX
770 * AML_NAME
771 * AML_NAMEDFIELD
772 * AML_OPREGION
773 * AML_POWERRES
774 * AML_PROCESSOR
775 * AML_SCOPE
776 * AML_THERMALZONE
777 */
778
779 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
780 "Create-Load [%s] State=%p Op=%p named_obj=%p\n",
781 acpi_ps_get_opcode_name (op->common.aml_opcode), walk_state, op, node));
782
783 /* Decode the opcode */
784
785 arg = op->common.value.arg;
786
787 switch (walk_state->op_info->type) {
788#ifndef ACPI_NO_METHOD_EXECUTION
789
790 case AML_TYPE_CREATE_FIELD:
791
792 /*
793 * Create the field object, but the field buffer and index must
794 * be evaluated later during the execution phase
795 */
796 status = acpi_ds_create_buffer_field (op, walk_state);
797 break;
798
799
800 case AML_TYPE_NAMED_FIELD:
801
802 switch (op->common.aml_opcode) {
803 case AML_INDEX_FIELD_OP:
804
805 status = acpi_ds_create_index_field (op, (acpi_handle) arg->common.node,
806 walk_state);
807 break;
808
809 case AML_BANK_FIELD_OP:
810
811 status = acpi_ds_create_bank_field (op, arg->common.node, walk_state);
812 break;
813
814 case AML_FIELD_OP:
815
816 status = acpi_ds_create_field (op, arg->common.node, walk_state);
817 break;
818
819 default:
820 /* All NAMED_FIELD opcodes must be handled above */
821 break;
822 }
823 break;
824
825
826 case AML_TYPE_NAMED_SIMPLE:
827
828 status = acpi_ds_create_operands (walk_state, arg);
829 if (ACPI_FAILURE (status)) {
830 goto cleanup;
831 }
832
833 switch (op->common.aml_opcode) {
834 case AML_PROCESSOR_OP:
835
836 status = acpi_ex_create_processor (walk_state);
837 break;
838
839 case AML_POWER_RES_OP:
840
841 status = acpi_ex_create_power_resource (walk_state);
842 break;
843
844 case AML_MUTEX_OP:
845
846 status = acpi_ex_create_mutex (walk_state);
847 break;
848
849 case AML_EVENT_OP:
850
851 status = acpi_ex_create_event (walk_state);
852 break;
853
854 case AML_DATA_REGION_OP:
855
856 status = acpi_ex_create_table_region (walk_state);
857 break;
858
859 case AML_ALIAS_OP:
860
861 status = acpi_ex_create_alias (walk_state);
862 break;
863
864 default:
865 /* Unknown opcode */
866
867 status = AE_OK;
868 goto cleanup;
869 }
870
871 /* Delete operands */
872
873 for (i = 1; i < walk_state->num_operands; i++) {
874 acpi_ut_remove_reference (walk_state->operands[i]);
875 walk_state->operands[i] = NULL;
876 }
877
878 break;
879#endif /* ACPI_NO_METHOD_EXECUTION */
880
881 case AML_TYPE_NAMED_COMPLEX:
882
883 switch (op->common.aml_opcode) {
884#ifndef ACPI_NO_METHOD_EXECUTION
885 case AML_REGION_OP:
886 /*
887 * The op_region is not fully parsed at this time. Only valid argument is the space_id.
888 * (We must save the address of the AML of the address and length operands)
889 */
890 /*
891 * If we have a valid region, initialize it
892 * Namespace is NOT locked at this point.
893 */
894 status = acpi_ev_initialize_region (acpi_ns_get_attached_object (node), FALSE);
895 if (ACPI_FAILURE (status)) {
896 /*
897 * If AE_NOT_EXIST is returned, it is not fatal
898 * because many regions get created before a handler
899 * is installed for said region.
900 */
901 if (AE_NOT_EXIST == status) {
902 status = AE_OK;
903 }
904 }
905 break;
906
907
908 case AML_NAME_OP:
909
910 status = acpi_ds_create_node (walk_state, node, op);
911 break;
912#endif /* ACPI_NO_METHOD_EXECUTION */
913
914
915 default:
916 /* All NAMED_COMPLEX opcodes must be handled above */
917 /* Note: Method objects were already created in Pass 1 */
918 break;
919 }
920 break;
921
922
923 case AML_CLASS_INTERNAL:
924
925 /* case AML_INT_NAMEPATH_OP: */
926 break;
927
928
929 case AML_CLASS_METHOD_CALL:
930
931 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
932 "RESOLVING-method_call: State=%p Op=%p named_obj=%p\n",
933 walk_state, op, node));
934
935 /*
936 * Lookup the method name and save the Node
937 */
938 status = acpi_ns_lookup (walk_state->scope_info, arg->common.value.string,
939 ACPI_TYPE_ANY, ACPI_IMODE_LOAD_PASS2,
940 ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE,
941 walk_state, &(new_node));
942 if (ACPI_SUCCESS (status)) {
943 /*
944 * Make sure that what we found is indeed a method
945 * We didn't search for a method on purpose, to see if the name would resolve
946 */
947 if (new_node->type != ACPI_TYPE_METHOD) {
948 status = AE_AML_OPERAND_TYPE;
949 }
950
951 /* We could put the returned object (Node) on the object stack for later, but
952 * for now, we will put it in the "op" object that the parser uses, so we
953 * can get it again at the end of this scope
954 */
955 op->common.node = new_node;
956 }
957 else {
958 ACPI_REPORT_NSERROR (arg->common.value.string, status);
959 }
960 break;
961
962
963 default:
964 break;
965 }
966
967cleanup:
968
969 /* Remove the Node pushed at the very beginning */
970
971 walk_state->operands[0] = NULL;
972 walk_state->num_operands = 0;
973 return_ACPI_STATUS (status);
974}
975
976
diff --git a/drivers/acpi/dispatcher/dswscope.c b/drivers/acpi/dispatcher/dswscope.c
new file mode 100644
index 000000000000..65f456151e25
--- /dev/null
+++ b/drivers/acpi/dispatcher/dswscope.c
@@ -0,0 +1,229 @@
1/******************************************************************************
2 *
3 * Module Name: dswscope - Scope stack manipulation
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2005, R. Byron Moore
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
45#include <acpi/acpi.h>
46#include <acpi/acdispat.h>
47
48
49#define _COMPONENT ACPI_DISPATCHER
50 ACPI_MODULE_NAME ("dswscope")
51
52
53#define STACK_POP(head) head
54
55
56/****************************************************************************
57 *
58 * FUNCTION: acpi_ds_scope_stack_clear
59 *
60 * PARAMETERS: None
61 *
62 * DESCRIPTION: Pop (and free) everything on the scope stack except the
63 * root scope object (which remains at the stack top.)
64 *
65 ***************************************************************************/
66
67void
68acpi_ds_scope_stack_clear (
69 struct acpi_walk_state *walk_state)
70{
71 union acpi_generic_state *scope_info;
72
73 ACPI_FUNCTION_NAME ("ds_scope_stack_clear");
74
75
76 while (walk_state->scope_info) {
77 /* Pop a scope off the stack */
78
79 scope_info = walk_state->scope_info;
80 walk_state->scope_info = scope_info->scope.next;
81
82 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
83 "Popped object type (%s)\n", acpi_ut_get_type_name (scope_info->common.value)));
84 acpi_ut_delete_generic_state (scope_info);
85 }
86}
87
88
89/****************************************************************************
90 *
91 * FUNCTION: acpi_ds_scope_stack_push
92 *
93 * PARAMETERS: *Node, - Name to be made current
94 * Type, - Type of frame being pushed
95 *
96 * DESCRIPTION: Push the current scope on the scope stack, and make the
97 * passed Node current.
98 *
99 ***************************************************************************/
100
101acpi_status
102acpi_ds_scope_stack_push (
103 struct acpi_namespace_node *node,
104 acpi_object_type type,
105 struct acpi_walk_state *walk_state)
106{
107 union acpi_generic_state *scope_info;
108 union acpi_generic_state *old_scope_info;
109
110
111 ACPI_FUNCTION_TRACE ("ds_scope_stack_push");
112
113
114 if (!node) {
115 /* Invalid scope */
116
117 ACPI_REPORT_ERROR (("ds_scope_stack_push: null scope passed\n"));
118 return_ACPI_STATUS (AE_BAD_PARAMETER);
119 }
120
121 /* Make sure object type is valid */
122
123 if (!acpi_ut_valid_object_type (type)) {
124 ACPI_REPORT_WARNING (("ds_scope_stack_push: Invalid object type: 0x%X\n", type));
125 }
126
127 /* Allocate a new scope object */
128
129 scope_info = acpi_ut_create_generic_state ();
130 if (!scope_info) {
131 return_ACPI_STATUS (AE_NO_MEMORY);
132 }
133
134 /* Init new scope object */
135
136 scope_info->common.data_type = ACPI_DESC_TYPE_STATE_WSCOPE;
137 scope_info->scope.node = node;
138 scope_info->common.value = (u16) type;
139
140 walk_state->scope_depth++;
141
142 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
143 "[%.2d] Pushed scope ", (u32) walk_state->scope_depth));
144
145 old_scope_info = walk_state->scope_info;
146 if (old_scope_info) {
147 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_EXEC,
148 "[%4.4s] (%s)",
149 acpi_ut_get_node_name (old_scope_info->scope.node),
150 acpi_ut_get_type_name (old_scope_info->common.value)));
151 }
152 else {
153 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_EXEC,
154 "[\\___] (%s)", "ROOT"));
155 }
156
157 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_EXEC,
158 ", New scope -> [%4.4s] (%s)\n",
159 acpi_ut_get_node_name (scope_info->scope.node),
160 acpi_ut_get_type_name (scope_info->common.value)));
161
162 /* Push new scope object onto stack */
163
164 acpi_ut_push_generic_state (&walk_state->scope_info, scope_info);
165 return_ACPI_STATUS (AE_OK);
166}
167
168
169/****************************************************************************
170 *
171 * FUNCTION: acpi_ds_scope_stack_pop
172 *
173 * PARAMETERS: Type - The type of frame to be found
174 *
175 * DESCRIPTION: Pop the scope stack until a frame of the requested type
176 * is found.
177 *
178 * RETURN: Count of frames popped. If no frame of the requested type
179 * was found, the count is returned as a negative number and
180 * the scope stack is emptied (which sets the current scope
181 * to the root). If the scope stack was empty at entry, the
182 * function is a no-op and returns 0.
183 *
184 ***************************************************************************/
185
186acpi_status
187acpi_ds_scope_stack_pop (
188 struct acpi_walk_state *walk_state)
189{
190 union acpi_generic_state *scope_info;
191 union acpi_generic_state *new_scope_info;
192
193
194 ACPI_FUNCTION_TRACE ("ds_scope_stack_pop");
195
196
197 /*
198 * Pop scope info object off the stack.
199 */
200 scope_info = acpi_ut_pop_generic_state (&walk_state->scope_info);
201 if (!scope_info) {
202 return_ACPI_STATUS (AE_STACK_UNDERFLOW);
203 }
204
205 walk_state->scope_depth--;
206
207 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
208 "[%.2d] Popped scope [%4.4s] (%s), New scope -> ",
209 (u32) walk_state->scope_depth,
210 acpi_ut_get_node_name (scope_info->scope.node),
211 acpi_ut_get_type_name (scope_info->common.value)));
212
213 new_scope_info = walk_state->scope_info;
214 if (new_scope_info) {
215 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_EXEC,
216 "[%4.4s] (%s)\n",
217 acpi_ut_get_node_name (new_scope_info->scope.node),
218 acpi_ut_get_type_name (new_scope_info->common.value)));
219 }
220 else {
221 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_EXEC,
222 "[\\___] (ROOT)\n"));
223 }
224
225 acpi_ut_delete_generic_state (scope_info);
226 return_ACPI_STATUS (AE_OK);
227}
228
229
diff --git a/drivers/acpi/dispatcher/dswstate.c b/drivers/acpi/dispatcher/dswstate.c
new file mode 100644
index 000000000000..e555b3fbd5e5
--- /dev/null
+++ b/drivers/acpi/dispatcher/dswstate.c
@@ -0,0 +1,1100 @@
1/******************************************************************************
2 *
3 * Module Name: dswstate - Dispatcher parse tree walk management routines
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2005, R. Byron Moore
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
45#include <acpi/acpi.h>
46#include <acpi/acparser.h>
47#include <acpi/acdispat.h>
48#include <acpi/acnamesp.h>
49
50#define _COMPONENT ACPI_DISPATCHER
51 ACPI_MODULE_NAME ("dswstate")
52
53
54#ifdef ACPI_FUTURE_USAGE
55
56/*******************************************************************************
57 *
58 * FUNCTION: acpi_ds_result_insert
59 *
60 * PARAMETERS: Object - Object to push
61 * Index - Where to insert the object
62 * walk_state - Current Walk state
63 *
64 * RETURN: Status
65 *
66 * DESCRIPTION: Insert an object onto this walk's result stack
67 *
68 ******************************************************************************/
69
70acpi_status
71acpi_ds_result_insert (
72 void *object,
73 u32 index,
74 struct acpi_walk_state *walk_state)
75{
76 union acpi_generic_state *state;
77
78
79 ACPI_FUNCTION_NAME ("ds_result_insert");
80
81
82 state = walk_state->results;
83 if (!state) {
84 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "No result object pushed! State=%p\n",
85 walk_state));
86 return (AE_NOT_EXIST);
87 }
88
89 if (index >= ACPI_OBJ_NUM_OPERANDS) {
90 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
91 "Index out of range: %X Obj=%p State=%p Num=%X\n",
92 index, object, walk_state, state->results.num_results));
93 return (AE_BAD_PARAMETER);
94 }
95
96 if (!object) {
97 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
98 "Null Object! Index=%X Obj=%p State=%p Num=%X\n",
99 index, object, walk_state, state->results.num_results));
100 return (AE_BAD_PARAMETER);
101 }
102
103 state->results.obj_desc [index] = object;
104 state->results.num_results++;
105
106 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
107 "Obj=%p [%s] State=%p Num=%X Cur=%X\n",
108 object, object ? acpi_ut_get_object_type_name ((union acpi_operand_object *) object) : "NULL",
109 walk_state, state->results.num_results, walk_state->current_result));
110
111 return (AE_OK);
112}
113
114
115/*******************************************************************************
116 *
117 * FUNCTION: acpi_ds_result_remove
118 *
119 * PARAMETERS: Object - Where to return the popped object
120 * Index - Where to extract the object
121 * walk_state - Current Walk state
122 *
123 * RETURN: Status
124 *
125 * DESCRIPTION: Pop an object off the bottom of this walk's result stack. In
126 * other words, this is a FIFO.
127 *
128 ******************************************************************************/
129
130acpi_status
131acpi_ds_result_remove (
132 union acpi_operand_object **object,
133 u32 index,
134 struct acpi_walk_state *walk_state)
135{
136 union acpi_generic_state *state;
137
138
139 ACPI_FUNCTION_NAME ("ds_result_remove");
140
141
142 state = walk_state->results;
143 if (!state) {
144 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "No result object pushed! State=%p\n",
145 walk_state));
146 return (AE_NOT_EXIST);
147 }
148
149 if (index >= ACPI_OBJ_MAX_OPERAND) {
150 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
151 "Index out of range: %X State=%p Num=%X\n",
152 index, walk_state, state->results.num_results));
153 }
154
155 /* Check for a valid result object */
156
157 if (!state->results.obj_desc [index]) {
158 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
159 "Null operand! State=%p #Ops=%X, Index=%X\n",
160 walk_state, state->results.num_results, index));
161 return (AE_AML_NO_RETURN_VALUE);
162 }
163
164 /* Remove the object */
165
166 state->results.num_results--;
167
168 *object = state->results.obj_desc [index];
169 state->results.obj_desc [index] = NULL;
170
171 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
172 "Obj=%p [%s] Index=%X State=%p Num=%X\n",
173 *object, (*object) ? acpi_ut_get_object_type_name (*object) : "NULL",
174 index, walk_state, state->results.num_results));
175
176 return (AE_OK);
177}
178
179#endif /* ACPI_FUTURE_USAGE */
180
181
182/*******************************************************************************
183 *
184 * FUNCTION: acpi_ds_result_pop
185 *
186 * PARAMETERS: Object - Where to return the popped object
187 * walk_state - Current Walk state
188 *
189 * RETURN: Status
190 *
191 * DESCRIPTION: Pop an object off the bottom of this walk's result stack. In
192 * other words, this is a FIFO.
193 *
194 ******************************************************************************/
195
196acpi_status
197acpi_ds_result_pop (
198 union acpi_operand_object **object,
199 struct acpi_walk_state *walk_state)
200{
201 acpi_native_uint index;
202 union acpi_generic_state *state;
203
204
205 ACPI_FUNCTION_NAME ("ds_result_pop");
206
207
208 state = walk_state->results;
209 if (!state) {
210 return (AE_OK);
211 }
212
213 if (!state->results.num_results) {
214 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Result stack is empty! State=%p\n",
215 walk_state));
216 return (AE_AML_NO_RETURN_VALUE);
217 }
218
219 /* Remove top element */
220
221 state->results.num_results--;
222
223 for (index = ACPI_OBJ_NUM_OPERANDS; index; index--) {
224 /* Check for a valid result object */
225
226 if (state->results.obj_desc [index -1]) {
227 *object = state->results.obj_desc [index -1];
228 state->results.obj_desc [index -1] = NULL;
229
230 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Obj=%p [%s] Index=%X State=%p Num=%X\n",
231 *object, (*object) ? acpi_ut_get_object_type_name (*object) : "NULL",
232 (u32) index -1, walk_state, state->results.num_results));
233
234 return (AE_OK);
235 }
236 }
237
238 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "No result objects! State=%p\n", walk_state));
239 return (AE_AML_NO_RETURN_VALUE);
240}
241
242
243/*******************************************************************************
244 *
245 * FUNCTION: acpi_ds_result_pop_from_bottom
246 *
247 * PARAMETERS: Object - Where to return the popped object
248 * walk_state - Current Walk state
249 *
250 * RETURN: Status
251 *
252 * DESCRIPTION: Pop an object off the bottom of this walk's result stack. In
253 * other words, this is a FIFO.
254 *
255 ******************************************************************************/
256
257acpi_status
258acpi_ds_result_pop_from_bottom (
259 union acpi_operand_object **object,
260 struct acpi_walk_state *walk_state)
261{
262 acpi_native_uint index;
263 union acpi_generic_state *state;
264
265
266 ACPI_FUNCTION_NAME ("ds_result_pop_from_bottom");
267
268
269 state = walk_state->results;
270 if (!state) {
271 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
272 "Warning: No result object pushed! State=%p\n", walk_state));
273 return (AE_NOT_EXIST);
274 }
275
276 if (!state->results.num_results) {
277 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "No result objects! State=%p\n", walk_state));
278 return (AE_AML_NO_RETURN_VALUE);
279 }
280
281 /* Remove Bottom element */
282
283 *object = state->results.obj_desc [0];
284
285 /* Push entire stack down one element */
286
287 for (index = 0; index < state->results.num_results; index++) {
288 state->results.obj_desc [index] = state->results.obj_desc [index + 1];
289 }
290
291 state->results.num_results--;
292
293 /* Check for a valid result object */
294
295 if (!*object) {
296 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Null operand! State=%p #Ops=%X, Index=%X\n",
297 walk_state, state->results.num_results, (u32) index));
298 return (AE_AML_NO_RETURN_VALUE);
299 }
300
301 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Obj=%p [%s], Results=%p State=%p\n",
302 *object, (*object) ? acpi_ut_get_object_type_name (*object) : "NULL",
303 state, walk_state));
304
305 return (AE_OK);
306}
307
308
309/*******************************************************************************
310 *
311 * FUNCTION: acpi_ds_result_push
312 *
313 * PARAMETERS: Object - Where to return the popped object
314 * walk_state - Current Walk state
315 *
316 * RETURN: Status
317 *
318 * DESCRIPTION: Push an object onto the current result stack
319 *
320 ******************************************************************************/
321
322acpi_status
323acpi_ds_result_push (
324 union acpi_operand_object *object,
325 struct acpi_walk_state *walk_state)
326{
327 union acpi_generic_state *state;
328
329
330 ACPI_FUNCTION_NAME ("ds_result_push");
331
332
333 state = walk_state->results;
334 if (!state) {
335 ACPI_REPORT_ERROR (("No result stack frame during push\n"));
336 return (AE_AML_INTERNAL);
337 }
338
339 if (state->results.num_results == ACPI_OBJ_NUM_OPERANDS) {
340 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
341 "Result stack overflow: Obj=%p State=%p Num=%X\n",
342 object, walk_state, state->results.num_results));
343 return (AE_STACK_OVERFLOW);
344 }
345
346 if (!object) {
347 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Null Object! Obj=%p State=%p Num=%X\n",
348 object, walk_state, state->results.num_results));
349 return (AE_BAD_PARAMETER);
350 }
351
352 state->results.obj_desc [state->results.num_results] = object;
353 state->results.num_results++;
354
355 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Obj=%p [%s] State=%p Num=%X Cur=%X\n",
356 object, object ? acpi_ut_get_object_type_name ((union acpi_operand_object *) object) : "NULL",
357 walk_state, state->results.num_results, walk_state->current_result));
358
359 return (AE_OK);
360}
361
362
363/*******************************************************************************
364 *
365 * FUNCTION: acpi_ds_result_stack_push
366 *
367 * PARAMETERS: walk_state - Current Walk state
368 *
369 * RETURN: Status
370 *
371 * DESCRIPTION: Push an object onto the walk_state result stack.
372 *
373 ******************************************************************************/
374
375acpi_status
376acpi_ds_result_stack_push (
377 struct acpi_walk_state *walk_state)
378{
379 union acpi_generic_state *state;
380
381 ACPI_FUNCTION_NAME ("ds_result_stack_push");
382
383
384 state = acpi_ut_create_generic_state ();
385 if (!state) {
386 return (AE_NO_MEMORY);
387 }
388
389 state->common.data_type = ACPI_DESC_TYPE_STATE_RESULT;
390 acpi_ut_push_generic_state (&walk_state->results, state);
391
392 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Results=%p State=%p\n",
393 state, walk_state));
394
395 return (AE_OK);
396}
397
398
399/*******************************************************************************
400 *
401 * FUNCTION: acpi_ds_result_stack_pop
402 *
403 * PARAMETERS: walk_state - Current Walk state
404 *
405 * RETURN: Status
406 *
407 * DESCRIPTION: Pop an object off of the walk_state result stack.
408 *
409 ******************************************************************************/
410
411acpi_status
412acpi_ds_result_stack_pop (
413 struct acpi_walk_state *walk_state)
414{
415 union acpi_generic_state *state;
416
417 ACPI_FUNCTION_NAME ("ds_result_stack_pop");
418
419
420 /* Check for stack underflow */
421
422 if (walk_state->results == NULL) {
423 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Underflow - State=%p\n",
424 walk_state));
425 return (AE_AML_NO_OPERAND);
426 }
427
428 state = acpi_ut_pop_generic_state (&walk_state->results);
429
430 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
431 "Result=%p remaining_results=%X State=%p\n",
432 state, state->results.num_results, walk_state));
433
434 acpi_ut_delete_generic_state (state);
435
436 return (AE_OK);
437}
438
439
440/*******************************************************************************
441 *
442 * FUNCTION: acpi_ds_obj_stack_delete_all
443 *
444 * PARAMETERS: walk_state - Current Walk state
445 *
446 * RETURN: Status
447 *
448 * DESCRIPTION: Clear the object stack by deleting all objects that are on it.
449 * Should be used with great care, if at all!
450 *
451 ******************************************************************************/
452#ifdef ACPI_FUTURE_USAGE
453acpi_status
454acpi_ds_obj_stack_delete_all (
455 struct acpi_walk_state *walk_state)
456{
457 u32 i;
458
459
460 ACPI_FUNCTION_TRACE_PTR ("ds_obj_stack_delete_all", walk_state);
461
462
463 /* The stack size is configurable, but fixed */
464
465 for (i = 0; i < ACPI_OBJ_NUM_OPERANDS; i++) {
466 if (walk_state->operands[i]) {
467 acpi_ut_remove_reference (walk_state->operands[i]);
468 walk_state->operands[i] = NULL;
469 }
470 }
471
472 return_ACPI_STATUS (AE_OK);
473}
474#endif /* ACPI_FUTURE_USAGE */
475
476
477/*******************************************************************************
478 *
479 * FUNCTION: acpi_ds_obj_stack_push
480 *
481 * PARAMETERS: Object - Object to push
482 * walk_state - Current Walk state
483 *
484 * RETURN: Status
485 *
486 * DESCRIPTION: Push an object onto this walk's object/operand stack
487 *
488 ******************************************************************************/
489
490acpi_status
491acpi_ds_obj_stack_push (
492 void *object,
493 struct acpi_walk_state *walk_state)
494{
495 ACPI_FUNCTION_NAME ("ds_obj_stack_push");
496
497
498 /* Check for stack overflow */
499
500 if (walk_state->num_operands >= ACPI_OBJ_NUM_OPERANDS) {
501 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
502 "overflow! Obj=%p State=%p #Ops=%X\n",
503 object, walk_state, walk_state->num_operands));
504 return (AE_STACK_OVERFLOW);
505 }
506
507 /* Put the object onto the stack */
508
509 walk_state->operands [walk_state->num_operands] = object;
510 walk_state->num_operands++;
511
512 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Obj=%p [%s] State=%p #Ops=%X\n",
513 object, acpi_ut_get_object_type_name ((union acpi_operand_object *) object),
514 walk_state, walk_state->num_operands));
515
516 return (AE_OK);
517}
518
519
520#if 0
521/*******************************************************************************
522 *
523 * FUNCTION: acpi_ds_obj_stack_pop_object
524 *
525 * PARAMETERS: pop_count - Number of objects/entries to pop
526 * walk_state - Current Walk state
527 *
528 * RETURN: Status
529 *
530 * DESCRIPTION: Pop this walk's object stack. Objects on the stack are NOT
531 * deleted by this routine.
532 *
533 ******************************************************************************/
534
535acpi_status
536acpi_ds_obj_stack_pop_object (
537 union acpi_operand_object **object,
538 struct acpi_walk_state *walk_state)
539{
540 ACPI_FUNCTION_NAME ("ds_obj_stack_pop_object");
541
542
543 /* Check for stack underflow */
544
545 if (walk_state->num_operands == 0) {
546 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
547 "Missing operand/stack empty! State=%p #Ops=%X\n",
548 walk_state, walk_state->num_operands));
549 *object = NULL;
550 return (AE_AML_NO_OPERAND);
551 }
552
553 /* Pop the stack */
554
555 walk_state->num_operands--;
556
557 /* Check for a valid operand */
558
559 if (!walk_state->operands [walk_state->num_operands]) {
560 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
561 "Null operand! State=%p #Ops=%X\n",
562 walk_state, walk_state->num_operands));
563 *object = NULL;
564 return (AE_AML_NO_OPERAND);
565 }
566
567 /* Get operand and set stack entry to null */
568
569 *object = walk_state->operands [walk_state->num_operands];
570 walk_state->operands [walk_state->num_operands] = NULL;
571
572 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Obj=%p [%s] State=%p #Ops=%X\n",
573 *object, acpi_ut_get_object_type_name (*object),
574 walk_state, walk_state->num_operands));
575
576 return (AE_OK);
577}
578#endif
579
580
581/*******************************************************************************
582 *
583 * FUNCTION: acpi_ds_obj_stack_pop
584 *
585 * PARAMETERS: pop_count - Number of objects/entries to pop
586 * walk_state - Current Walk state
587 *
588 * RETURN: Status
589 *
590 * DESCRIPTION: Pop this walk's object stack. Objects on the stack are NOT
591 * deleted by this routine.
592 *
593 ******************************************************************************/
594
595acpi_status
596acpi_ds_obj_stack_pop (
597 u32 pop_count,
598 struct acpi_walk_state *walk_state)
599{
600 u32 i;
601
602 ACPI_FUNCTION_NAME ("ds_obj_stack_pop");
603
604
605 for (i = 0; i < pop_count; i++) {
606 /* Check for stack underflow */
607
608 if (walk_state->num_operands == 0) {
609 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
610 "Underflow! Count=%X State=%p #Ops=%X\n",
611 pop_count, walk_state, walk_state->num_operands));
612 return (AE_STACK_UNDERFLOW);
613 }
614
615 /* Just set the stack entry to null */
616
617 walk_state->num_operands--;
618 walk_state->operands [walk_state->num_operands] = NULL;
619 }
620
621 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Count=%X State=%p #Ops=%X\n",
622 pop_count, walk_state, walk_state->num_operands));
623
624 return (AE_OK);
625}
626
627
628/*******************************************************************************
629 *
630 * FUNCTION: acpi_ds_obj_stack_pop_and_delete
631 *
632 * PARAMETERS: pop_count - Number of objects/entries to pop
633 * walk_state - Current Walk state
634 *
635 * RETURN: Status
636 *
637 * DESCRIPTION: Pop this walk's object stack and delete each object that is
638 * popped off.
639 *
640 ******************************************************************************/
641
642acpi_status
643acpi_ds_obj_stack_pop_and_delete (
644 u32 pop_count,
645 struct acpi_walk_state *walk_state)
646{
647 u32 i;
648 union acpi_operand_object *obj_desc;
649
650
651 ACPI_FUNCTION_NAME ("ds_obj_stack_pop_and_delete");
652
653
654 for (i = 0; i < pop_count; i++) {
655 /* Check for stack underflow */
656
657 if (walk_state->num_operands == 0) {
658 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
659 "Underflow! Count=%X State=%p #Ops=%X\n",
660 pop_count, walk_state, walk_state->num_operands));
661 return (AE_STACK_UNDERFLOW);
662 }
663
664 /* Pop the stack and delete an object if present in this stack entry */
665
666 walk_state->num_operands--;
667 obj_desc = walk_state->operands [walk_state->num_operands];
668 if (obj_desc) {
669 acpi_ut_remove_reference (walk_state->operands [walk_state->num_operands]);
670 walk_state->operands [walk_state->num_operands] = NULL;
671 }
672 }
673
674 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Count=%X State=%p #Ops=%X\n",
675 pop_count, walk_state, walk_state->num_operands));
676
677 return (AE_OK);
678}
679
680
681/*******************************************************************************
682 *
683 * FUNCTION: acpi_ds_obj_stack_get_value
684 *
685 * PARAMETERS: Index - Stack index whose value is desired. Based
686 * on the top of the stack (index=0 == top)
687 * walk_state - Current Walk state
688 *
689 * RETURN: Status
690 *
691 * DESCRIPTION: Retrieve an object from this walk's object stack. Index must
692 * be within the range of the current stack pointer.
693 *
694 ******************************************************************************/
695#ifdef ACPI_FUTURE_USAGE
696void *
697acpi_ds_obj_stack_get_value (
698 u32 index,
699 struct acpi_walk_state *walk_state)
700{
701
702 ACPI_FUNCTION_TRACE_PTR ("ds_obj_stack_get_value", walk_state);
703
704
705 /* Can't do it if the stack is empty */
706
707 if (walk_state->num_operands == 0) {
708 return_PTR (NULL);
709 }
710
711 /* or if the index is past the top of the stack */
712
713 if (index > (walk_state->num_operands - (u32) 1)) {
714 return_PTR (NULL);
715 }
716
717 return_PTR (walk_state->operands[(acpi_native_uint)(walk_state->num_operands - 1) -
718 index]);
719}
720#endif /* ACPI_FUTURE_USAGE */
721
722
723/*******************************************************************************
724 *
725 * FUNCTION: acpi_ds_get_current_walk_state
726 *
727 * PARAMETERS: Thread - Get current active state for this Thread
728 *
729 * RETURN: Pointer to the current walk state
730 *
731 * DESCRIPTION: Get the walk state that is at the head of the list (the "current"
732 * walk state.)
733 *
734 ******************************************************************************/
735
736struct acpi_walk_state *
737acpi_ds_get_current_walk_state (
738 struct acpi_thread_state *thread)
739
740{
741 ACPI_FUNCTION_NAME ("ds_get_current_walk_state");
742
743
744 if (!thread) {
745 return (NULL);
746 }
747
748 ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Current walk_state %p\n",
749 thread->walk_state_list));
750
751 return (thread->walk_state_list);
752}
753
754
755/*******************************************************************************
756 *
757 * FUNCTION: acpi_ds_push_walk_state
758 *
759 * PARAMETERS: walk_state - State to push
760 * walk_list - The list that owns the walk stack
761 *
762 * RETURN: None
763 *
764 * DESCRIPTION: Place the walk_state at the head of the state list.
765 *
766 ******************************************************************************/
767
768void
769acpi_ds_push_walk_state (
770 struct acpi_walk_state *walk_state,
771 struct acpi_thread_state *thread)
772{
773 ACPI_FUNCTION_TRACE ("ds_push_walk_state");
774
775
776 walk_state->next = thread->walk_state_list;
777 thread->walk_state_list = walk_state;
778
779 return_VOID;
780}
781
782
783/*******************************************************************************
784 *
785 * FUNCTION: acpi_ds_pop_walk_state
786 *
787 * PARAMETERS: walk_list - The list that owns the walk stack
788 *
789 * RETURN: A walk_state object popped from the stack
790 *
791 * DESCRIPTION: Remove and return the walkstate object that is at the head of
792 * the walk stack for the given walk list. NULL indicates that
793 * the list is empty.
794 *
795 ******************************************************************************/
796
797struct acpi_walk_state *
798acpi_ds_pop_walk_state (
799 struct acpi_thread_state *thread)
800{
801 struct acpi_walk_state *walk_state;
802
803
804 ACPI_FUNCTION_TRACE ("ds_pop_walk_state");
805
806
807 walk_state = thread->walk_state_list;
808
809 if (walk_state) {
810 /* Next walk state becomes the current walk state */
811
812 thread->walk_state_list = walk_state->next;
813
814 /*
815 * Don't clear the NEXT field, this serves as an indicator
816 * that there is a parent WALK STATE
817 * NO: walk_state->Next = NULL;
818 */
819 }
820
821 return_PTR (walk_state);
822}
823
824
825/*******************************************************************************
826 *
827 * FUNCTION: acpi_ds_create_walk_state
828 *
829 * PARAMETERS: Origin - Starting point for this walk
830 * Thread - Current thread state
831 *
832 * RETURN: Pointer to the new walk state.
833 *
834 * DESCRIPTION: Allocate and initialize a new walk state. The current walk
835 * state is set to this new state.
836 *
837 ******************************************************************************/
838
839struct acpi_walk_state *
840acpi_ds_create_walk_state (
841 acpi_owner_id owner_id,
842 union acpi_parse_object *origin,
843 union acpi_operand_object *mth_desc,
844 struct acpi_thread_state *thread)
845{
846 struct acpi_walk_state *walk_state;
847 acpi_status status;
848
849
850 ACPI_FUNCTION_TRACE ("ds_create_walk_state");
851
852
853 walk_state = acpi_ut_acquire_from_cache (ACPI_MEM_LIST_WALK);
854 if (!walk_state) {
855 return_PTR (NULL);
856 }
857
858 walk_state->data_type = ACPI_DESC_TYPE_WALK;
859 walk_state->owner_id = owner_id;
860 walk_state->origin = origin;
861 walk_state->method_desc = mth_desc;
862 walk_state->thread = thread;
863
864 walk_state->parser_state.start_op = origin;
865
866 /* Init the method args/local */
867
868#if (!defined (ACPI_NO_METHOD_EXECUTION) && !defined (ACPI_CONSTANT_EVAL_ONLY))
869 acpi_ds_method_data_init (walk_state);
870#endif
871
872 /* Create an initial result stack entry */
873
874 status = acpi_ds_result_stack_push (walk_state);
875 if (ACPI_FAILURE (status)) {
876 acpi_ut_release_to_cache (ACPI_MEM_LIST_WALK, walk_state);
877 return_PTR (NULL);
878 }
879
880 /* Put the new state at the head of the walk list */
881
882 if (thread) {
883 acpi_ds_push_walk_state (walk_state, thread);
884 }
885
886 return_PTR (walk_state);
887}
888
889
890/*******************************************************************************
891 *
892 * FUNCTION: acpi_ds_init_aml_walk
893 *
894 * PARAMETERS: walk_state - New state to be initialized
895 * Op - Current parse op
896 * method_node - Control method NS node, if any
897 * aml_start - Start of AML
898 * aml_length - Length of AML
899 * Params - Method args, if any
900 * return_obj_desc - Where to store a return object, if any
901 * pass_number - 1, 2, or 3
902 *
903 * RETURN: Status
904 *
905 * DESCRIPTION: Initialize a walk state for a pass 1 or 2 parse tree walk
906 *
907 ******************************************************************************/
908
909acpi_status
910acpi_ds_init_aml_walk (
911 struct acpi_walk_state *walk_state,
912 union acpi_parse_object *op,
913 struct acpi_namespace_node *method_node,
914 u8 *aml_start,
915 u32 aml_length,
916 struct acpi_parameter_info *info,
917 u32 pass_number)
918{
919 acpi_status status;
920 struct acpi_parse_state *parser_state = &walk_state->parser_state;
921 union acpi_parse_object *extra_op;
922
923
924 ACPI_FUNCTION_TRACE ("ds_init_aml_walk");
925
926
927 walk_state->parser_state.aml =
928 walk_state->parser_state.aml_start = aml_start;
929 walk_state->parser_state.aml_end =
930 walk_state->parser_state.pkg_end = aml_start + aml_length;
931
932 /* The next_op of the next_walk will be the beginning of the method */
933
934 walk_state->next_op = NULL;
935
936 if (info) {
937 if (info->parameter_type == ACPI_PARAM_GPE) {
938 walk_state->gpe_event_info = ACPI_CAST_PTR (struct acpi_gpe_event_info,
939 info->parameters);
940 }
941 else {
942 walk_state->params = info->parameters;
943 walk_state->caller_return_desc = &info->return_object;
944 }
945 }
946
947 status = acpi_ps_init_scope (&walk_state->parser_state, op);
948 if (ACPI_FAILURE (status)) {
949 return_ACPI_STATUS (status);
950 }
951
952 if (method_node) {
953 walk_state->parser_state.start_node = method_node;
954 walk_state->walk_type = ACPI_WALK_METHOD;
955 walk_state->method_node = method_node;
956 walk_state->method_desc = acpi_ns_get_attached_object (method_node);
957
958 /* Push start scope on scope stack and make it current */
959
960 status = acpi_ds_scope_stack_push (method_node, ACPI_TYPE_METHOD, walk_state);
961 if (ACPI_FAILURE (status)) {
962 return_ACPI_STATUS (status);
963 }
964
965 /* Init the method arguments */
966
967 status = acpi_ds_method_data_init_args (walk_state->params, ACPI_METHOD_NUM_ARGS, walk_state);
968 if (ACPI_FAILURE (status)) {
969 return_ACPI_STATUS (status);
970 }
971 }
972 else {
973 /*
974 * Setup the current scope.
975 * Find a Named Op that has a namespace node associated with it.
976 * search upwards from this Op. Current scope is the first
977 * Op with a namespace node.
978 */
979 extra_op = parser_state->start_op;
980 while (extra_op && !extra_op->common.node) {
981 extra_op = extra_op->common.parent;
982 }
983
984 if (!extra_op) {
985 parser_state->start_node = NULL;
986 }
987 else {
988 parser_state->start_node = extra_op->common.node;
989 }
990
991 if (parser_state->start_node) {
992 /* Push start scope on scope stack and make it current */
993
994 status = acpi_ds_scope_stack_push (parser_state->start_node,
995 parser_state->start_node->type, walk_state);
996 if (ACPI_FAILURE (status)) {
997 return_ACPI_STATUS (status);
998 }
999 }
1000 }
1001
1002 status = acpi_ds_init_callbacks (walk_state, pass_number);
1003 return_ACPI_STATUS (status);
1004}
1005
1006
1007/*******************************************************************************
1008 *
1009 * FUNCTION: acpi_ds_delete_walk_state
1010 *
1011 * PARAMETERS: walk_state - State to delete
1012 *
1013 * RETURN: Status
1014 *
1015 * DESCRIPTION: Delete a walk state including all internal data structures
1016 *
1017 ******************************************************************************/
1018
1019void
1020acpi_ds_delete_walk_state (
1021 struct acpi_walk_state *walk_state)
1022{
1023 union acpi_generic_state *state;
1024
1025
1026 ACPI_FUNCTION_TRACE_PTR ("ds_delete_walk_state", walk_state);
1027
1028
1029 if (!walk_state) {
1030 return;
1031 }
1032
1033 if (walk_state->data_type != ACPI_DESC_TYPE_WALK) {
1034 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "%p is not a valid walk state\n", walk_state));
1035 return;
1036 }
1037
1038 if (walk_state->parser_state.scope) {
1039 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "%p walk still has a scope list\n", walk_state));
1040 }
1041
1042 /* Always must free any linked control states */
1043
1044 while (walk_state->control_state) {
1045 state = walk_state->control_state;
1046 walk_state->control_state = state->common.next;
1047
1048 acpi_ut_delete_generic_state (state);
1049 }
1050
1051 /* Always must free any linked parse states */
1052
1053 while (walk_state->scope_info) {
1054 state = walk_state->scope_info;
1055 walk_state->scope_info = state->common.next;
1056
1057 acpi_ut_delete_generic_state (state);
1058 }
1059
1060 /* Always must free any stacked result states */
1061
1062 while (walk_state->results) {
1063 state = walk_state->results;
1064 walk_state->results = state->common.next;
1065
1066 acpi_ut_delete_generic_state (state);
1067 }
1068
1069 acpi_ut_release_to_cache (ACPI_MEM_LIST_WALK, walk_state);
1070 return_VOID;
1071}
1072
1073
1074#ifdef ACPI_ENABLE_OBJECT_CACHE
1075/******************************************************************************
1076 *
1077 * FUNCTION: acpi_ds_delete_walk_state_cache
1078 *
1079 * PARAMETERS: None
1080 *
1081 * RETURN: Status
1082 *
1083 * DESCRIPTION: Purge the global state object cache. Used during subsystem
1084 * termination.
1085 *
1086 ******************************************************************************/
1087
1088void
1089acpi_ds_delete_walk_state_cache (
1090 void)
1091{
1092 ACPI_FUNCTION_TRACE ("ds_delete_walk_state_cache");
1093
1094
1095 acpi_ut_delete_generic_cache (ACPI_MEM_LIST_WALK);
1096 return_VOID;
1097}
1098#endif
1099
1100