ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.6.tar.bz2
[linux-2.6.git] / drivers / acpi / dispatcher / dsopcode.c
1 /******************************************************************************
2  *
3  * Module Name: dsopcode - Dispatcher Op Region support and handling of
4  *                         "control" opcodes
5  *
6  *****************************************************************************/
7
8 /*
9  * Copyright (C) 2000 - 2004, 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
72 acpi_status
73 acpi_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         union acpi_parse_object         *arg;
83
84
85         ACPI_FUNCTION_TRACE ("ds_execute_arguments");
86
87
88         /*
89          * Allocate a new parser op to be the root of the parsed tree
90          */
91         op = acpi_ps_alloc_op (AML_INT_EVAL_SUBTREE_OP);
92         if (!op) {
93                 return_ACPI_STATUS (AE_NO_MEMORY);
94         }
95
96         /* Save the Node for use in acpi_ps_parse_aml */
97
98         op->common.node = scope_node;
99
100         /* Create and initialize a new parser state */
101
102         walk_state = acpi_ds_create_walk_state (0, NULL, NULL, NULL);
103         if (!walk_state) {
104                 return_ACPI_STATUS (AE_NO_MEMORY);
105         }
106
107         status = acpi_ds_init_aml_walk (walk_state, op, NULL, aml_start,
108                           aml_length, NULL, NULL, 1);
109         if (ACPI_FAILURE (status)) {
110                 acpi_ds_delete_walk_state (walk_state);
111                 return_ACPI_STATUS (status);
112         }
113
114         /* Mark this parse as a deferred opcode */
115
116         walk_state->parse_flags = ACPI_PARSE_DEFERRED_OP;
117         walk_state->deferred_node = node;
118
119         /* Pass1: Parse the entire declaration */
120
121         status = acpi_ps_parse_aml (walk_state);
122         if (ACPI_FAILURE (status)) {
123                 acpi_ps_delete_parse_tree (op);
124                 return_ACPI_STATUS (status);
125         }
126
127         /* Get and init the Op created above */
128
129         arg = op->common.value.arg;
130         op->common.node = node;
131         arg->common.node = node;
132         acpi_ps_delete_parse_tree (op);
133
134         /* Evaluate the deferred arguments */
135
136         op = acpi_ps_alloc_op (AML_INT_EVAL_SUBTREE_OP);
137         if (!op) {
138                 return_ACPI_STATUS (AE_NO_MEMORY);
139         }
140
141         op->common.node = scope_node;
142
143         /* Create and initialize a new parser state */
144
145         walk_state = acpi_ds_create_walk_state (0, NULL, NULL, NULL);
146         if (!walk_state) {
147                 return_ACPI_STATUS (AE_NO_MEMORY);
148         }
149
150         /* Execute the opcode and arguments */
151
152         status = acpi_ds_init_aml_walk (walk_state, op, NULL, aml_start,
153                           aml_length, NULL, NULL, 3);
154         if (ACPI_FAILURE (status)) {
155                 acpi_ds_delete_walk_state (walk_state);
156                 return_ACPI_STATUS (status);
157         }
158
159         /* Mark this execution as a deferred opcode */
160
161         walk_state->deferred_node = node;
162         status = acpi_ps_parse_aml (walk_state);
163         acpi_ps_delete_parse_tree (op);
164         return_ACPI_STATUS (status);
165 }
166
167
168 /*****************************************************************************
169  *
170  * FUNCTION:    acpi_ds_get_buffer_field_arguments
171  *
172  * PARAMETERS:  obj_desc        - A valid buffer_field object
173  *
174  * RETURN:      Status.
175  *
176  * DESCRIPTION: Get buffer_field Buffer and Index. This implements the late
177  *              evaluation of these field attributes.
178  *
179  ****************************************************************************/
180
181 acpi_status
182 acpi_ds_get_buffer_field_arguments (
183         union acpi_operand_object       *obj_desc)
184 {
185         union acpi_operand_object       *extra_desc;
186         struct acpi_namespace_node      *node;
187         acpi_status                     status;
188
189
190         ACPI_FUNCTION_TRACE_PTR ("ds_get_buffer_field_arguments", obj_desc);
191
192
193         if (obj_desc->common.flags & AOPOBJ_DATA_VALID) {
194                 return_ACPI_STATUS (AE_OK);
195         }
196
197         /* Get the AML pointer (method object) and buffer_field node */
198
199         extra_desc = acpi_ns_get_secondary_object (obj_desc);
200         node = obj_desc->buffer_field.node;
201
202         ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname (ACPI_TYPE_BUFFER_FIELD, node, NULL));
203         ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[%4.4s] buffer_field Arg Init\n",
204                 acpi_ut_get_node_name (node)));
205
206         /* Execute the AML code for the term_arg arguments */
207
208         status = acpi_ds_execute_arguments (node, acpi_ns_get_parent_node (node),
209                          extra_desc->extra.aml_length, extra_desc->extra.aml_start);
210         return_ACPI_STATUS (status);
211 }
212
213
214 /*****************************************************************************
215  *
216  * FUNCTION:    acpi_ds_get_buffer_arguments
217  *
218  * PARAMETERS:  obj_desc        - A valid Buffer object
219  *
220  * RETURN:      Status.
221  *
222  * DESCRIPTION: Get Buffer length and initializer byte list.  This implements
223  *              the late evaluation of these attributes.
224  *
225  ****************************************************************************/
226
227 acpi_status
228 acpi_ds_get_buffer_arguments (
229         union acpi_operand_object       *obj_desc)
230 {
231         struct acpi_namespace_node      *node;
232         acpi_status                     status;
233
234
235         ACPI_FUNCTION_TRACE_PTR ("ds_get_buffer_arguments", obj_desc);
236
237
238         if (obj_desc->common.flags & AOPOBJ_DATA_VALID) {
239                 return_ACPI_STATUS (AE_OK);
240         }
241
242         /* Get the Buffer node */
243
244         node = obj_desc->buffer.node;
245         if (!node) {
246                 ACPI_REPORT_ERROR ((
247                                 "No pointer back to NS node in buffer obj %p\n", obj_desc));
248                 return_ACPI_STATUS (AE_AML_INTERNAL);
249         }
250
251         ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Buffer Arg Init\n"));
252
253         /* Execute the AML code for the term_arg arguments */
254
255         status = acpi_ds_execute_arguments (node, node,
256                          obj_desc->buffer.aml_length, obj_desc->buffer.aml_start);
257         return_ACPI_STATUS (status);
258 }
259
260
261 /*****************************************************************************
262  *
263  * FUNCTION:    acpi_ds_get_package_arguments
264  *
265  * PARAMETERS:  obj_desc        - A valid Package object
266  *
267  * RETURN:      Status.
268  *
269  * DESCRIPTION: Get Package length and initializer byte list.  This implements
270  *              the late evaluation of these attributes.
271  *
272  ****************************************************************************/
273
274 acpi_status
275 acpi_ds_get_package_arguments (
276         union acpi_operand_object       *obj_desc)
277 {
278         struct acpi_namespace_node      *node;
279         acpi_status                     status;
280
281
282         ACPI_FUNCTION_TRACE_PTR ("ds_get_package_arguments", obj_desc);
283
284
285         if (obj_desc->common.flags & AOPOBJ_DATA_VALID) {
286                 return_ACPI_STATUS (AE_OK);
287         }
288
289         /* Get the Package node */
290
291         node = obj_desc->package.node;
292         if (!node) {
293                 ACPI_REPORT_ERROR ((
294                                 "No pointer back to NS node in package %p\n", obj_desc));
295                 return_ACPI_STATUS (AE_AML_INTERNAL);
296         }
297
298         ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Package Arg Init\n"));
299
300         /* Execute the AML code for the term_arg arguments */
301
302         status = acpi_ds_execute_arguments (node, node,
303                          obj_desc->package.aml_length, obj_desc->package.aml_start);
304         return_ACPI_STATUS (status);
305 }
306
307
308 /*****************************************************************************
309  *
310  * FUNCTION:    acpi_ds_get_region_arguments
311  *
312  * PARAMETERS:  obj_desc        - A valid region object
313  *
314  * RETURN:      Status.
315  *
316  * DESCRIPTION: Get region address and length.  This implements the late
317  *              evaluation of these region attributes.
318  *
319  ****************************************************************************/
320
321 acpi_status
322 acpi_ds_get_region_arguments (
323         union acpi_operand_object       *obj_desc)
324 {
325         struct acpi_namespace_node      *node;
326         acpi_status                     status;
327         union acpi_operand_object       *extra_desc;
328
329
330         ACPI_FUNCTION_TRACE_PTR ("ds_get_region_arguments", obj_desc);
331
332
333         if (obj_desc->region.flags & AOPOBJ_DATA_VALID) {
334                 return_ACPI_STATUS (AE_OK);
335         }
336
337         extra_desc = acpi_ns_get_secondary_object (obj_desc);
338         if (!extra_desc) {
339                 return_ACPI_STATUS (AE_NOT_EXIST);
340         }
341
342         /* Get the Region node */
343
344         node = obj_desc->region.node;
345
346         ACPI_DEBUG_EXEC (acpi_ut_display_init_pathname (ACPI_TYPE_REGION, node, NULL));
347
348         ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[%4.4s] op_region Arg Init at AML %p\n",
349                 acpi_ut_get_node_name (node), extra_desc->extra.aml_start));
350
351         /* Execute the argument AML */
352
353         status = acpi_ds_execute_arguments (node, acpi_ns_get_parent_node (node),
354                          extra_desc->extra.aml_length, extra_desc->extra.aml_start);
355         return_ACPI_STATUS (status);
356 }
357
358
359 /*****************************************************************************
360  *
361  * FUNCTION:    acpi_ds_initialize_region
362  *
363  * PARAMETERS:  Op              - A valid region Op object
364  *
365  * RETURN:      Status
366  *
367  * DESCRIPTION: Front end to ev_initialize_region
368  *
369  ****************************************************************************/
370
371 acpi_status
372 acpi_ds_initialize_region (
373         acpi_handle                     obj_handle)
374 {
375         union acpi_operand_object       *obj_desc;
376         acpi_status                     status;
377
378
379         obj_desc = acpi_ns_get_attached_object (obj_handle);
380
381         /* Namespace is NOT locked */
382
383         status = acpi_ev_initialize_region (obj_desc, FALSE);
384         return (status);
385 }
386
387
388 /*****************************************************************************
389  *
390  * FUNCTION:    acpi_ds_init_buffer_field
391  *
392  * PARAMETERS:  aml_opcode      - create_xxx_field
393  *              obj_desc        - buffer_field object
394  *              buffer_desc     - Host Buffer
395  *              offset_desc     - Offset into buffer
396  *              Length          - Length of field (CREATE_FIELD_OP only)
397  *              Result          - Where to store the result
398  *
399  * RETURN:      Status
400  *
401  * DESCRIPTION: Perform actual initialization of a buffer field
402  *
403  ****************************************************************************/
404
405 acpi_status
406 acpi_ds_init_buffer_field (
407         u16                             aml_opcode,
408         union acpi_operand_object       *obj_desc,
409         union acpi_operand_object       *buffer_desc,
410         union acpi_operand_object       *offset_desc,
411         union acpi_operand_object       *length_desc,
412         union acpi_operand_object       *result_desc)
413 {
414         u32                             offset;
415         u32                             bit_offset;
416         u32                             bit_count;
417         u8                              field_flags;
418         acpi_status                     status;
419
420
421         ACPI_FUNCTION_TRACE_PTR ("ds_init_buffer_field", obj_desc);
422
423
424         /* Host object must be a Buffer */
425
426         if (ACPI_GET_OBJECT_TYPE (buffer_desc) != ACPI_TYPE_BUFFER) {
427                 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
428                         "Target of Create Field is not a Buffer object - %s\n",
429                         acpi_ut_get_object_type_name (buffer_desc)));
430
431                 status = AE_AML_OPERAND_TYPE;
432                 goto cleanup;
433         }
434
435         /*
436          * The last parameter to all of these opcodes (result_desc) started
437          * out as a name_string, and should therefore now be a NS node
438          * after resolution in acpi_ex_resolve_operands().
439          */
440         if (ACPI_GET_DESCRIPTOR_TYPE (result_desc) != ACPI_DESC_TYPE_NAMED) {
441                 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "(%s) destination not a NS Node [%s]\n",
442                                 acpi_ps_get_opcode_name (aml_opcode), acpi_ut_get_descriptor_name (result_desc)));
443
444                 status = AE_AML_OPERAND_TYPE;
445                 goto cleanup;
446         }
447
448         offset = (u32) offset_desc->integer.value;
449
450         /*
451          * Setup the Bit offsets and counts, according to the opcode
452          */
453         switch (aml_opcode) {
454         case AML_CREATE_FIELD_OP:
455
456                 /* Offset is in bits, count is in bits */
457
458                 bit_offset = offset;
459                 bit_count  = (u32) length_desc->integer.value;
460                 field_flags = AML_FIELD_ACCESS_BYTE;
461                 break;
462
463         case AML_CREATE_BIT_FIELD_OP:
464
465                 /* Offset is in bits, Field is one bit */
466
467                 bit_offset = offset;
468                 bit_count  = 1;
469                 field_flags = AML_FIELD_ACCESS_BYTE;
470                 break;
471
472         case AML_CREATE_BYTE_FIELD_OP:
473
474                 /* Offset is in bytes, field is one byte */
475
476                 bit_offset = 8 * offset;
477                 bit_count  = 8;
478                 field_flags = AML_FIELD_ACCESS_BYTE;
479                 break;
480
481         case AML_CREATE_WORD_FIELD_OP:
482
483                 /* Offset is in bytes, field is one word */
484
485                 bit_offset = 8 * offset;
486                 bit_count  = 16;
487                 field_flags = AML_FIELD_ACCESS_WORD;
488                 break;
489
490         case AML_CREATE_DWORD_FIELD_OP:
491
492                 /* Offset is in bytes, field is one dword */
493
494                 bit_offset = 8 * offset;
495                 bit_count  = 32;
496                 field_flags = AML_FIELD_ACCESS_DWORD;
497                 break;
498
499         case AML_CREATE_QWORD_FIELD_OP:
500
501                 /* Offset is in bytes, field is one qword */
502
503                 bit_offset = 8 * offset;
504                 bit_count  = 64;
505                 field_flags = AML_FIELD_ACCESS_QWORD;
506                 break;
507
508         default:
509
510                 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
511                         "Unknown field creation opcode %02x\n",
512                         aml_opcode));
513                 status = AE_AML_BAD_OPCODE;
514                 goto cleanup;
515         }
516
517         /* Entire field must fit within the current length of the buffer */
518
519         if ((bit_offset + bit_count) >
520                 (8 * (u32) buffer_desc->buffer.length)) {
521                 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
522                         "Field [%4.4s] size %d exceeds Buffer [%4.4s] size %d (bits)\n",
523                          acpi_ut_get_node_name (result_desc),
524                          bit_offset + bit_count,
525                          acpi_ut_get_node_name (buffer_desc->buffer.node),
526                          8 * (u32) buffer_desc->buffer.length));
527                 status = AE_AML_BUFFER_LIMIT;
528                 goto cleanup;
529         }
530
531         /*
532          * Initialize areas of the field object that are common to all fields
533          * For field_flags, use LOCK_RULE = 0 (NO_LOCK), UPDATE_RULE = 0 (UPDATE_PRESERVE)
534          */
535         status = acpi_ex_prep_common_field_object (obj_desc, field_flags, 0,
536                           bit_offset, bit_count);
537         if (ACPI_FAILURE (status)) {
538                 goto cleanup;
539         }
540
541         obj_desc->buffer_field.buffer_obj = buffer_desc;
542
543         /* Reference count for buffer_desc inherits obj_desc count */
544
545         buffer_desc->common.reference_count = (u16) (buffer_desc->common.reference_count +
546                           obj_desc->common.reference_count);
547
548
549 cleanup:
550
551         /* Always delete the operands */
552
553         acpi_ut_remove_reference (offset_desc);
554         acpi_ut_remove_reference (buffer_desc);
555
556         if (aml_opcode == AML_CREATE_FIELD_OP) {
557                 acpi_ut_remove_reference (length_desc);
558         }
559
560         /* On failure, delete the result descriptor */
561
562         if (ACPI_FAILURE (status)) {
563                 acpi_ut_remove_reference (result_desc); /* Result descriptor */
564         }
565         else {
566                 /* Now the address and length are valid for this buffer_field */
567
568                 obj_desc->buffer_field.flags |= AOPOBJ_DATA_VALID;
569         }
570
571         return_ACPI_STATUS (status);
572 }
573
574
575 /*****************************************************************************
576  *
577  * FUNCTION:    acpi_ds_eval_buffer_field_operands
578  *
579  * PARAMETERS:  walk_state      - Current walk
580  *              Op              - A valid buffer_field Op object
581  *
582  * RETURN:      Status
583  *
584  * DESCRIPTION: Get buffer_field Buffer and Index
585  *              Called from acpi_ds_exec_end_op during buffer_field parse tree walk
586  *
587  ****************************************************************************/
588
589 acpi_status
590 acpi_ds_eval_buffer_field_operands (
591         struct acpi_walk_state          *walk_state,
592         union acpi_parse_object         *op)
593 {
594         acpi_status                     status;
595         union acpi_operand_object       *obj_desc;
596         struct acpi_namespace_node      *node;
597         union acpi_parse_object         *next_op;
598
599
600         ACPI_FUNCTION_TRACE_PTR ("ds_eval_buffer_field_operands", op);
601
602
603         /*
604          * This is where we evaluate the address and length fields of the
605          * create_xxx_field declaration
606          */
607         node =  op->common.node;
608
609         /* next_op points to the op that holds the Buffer */
610
611         next_op = op->common.value.arg;
612
613         /* Evaluate/create the address and length operands */
614
615         status = acpi_ds_create_operands (walk_state, next_op);
616         if (ACPI_FAILURE (status)) {
617                 return_ACPI_STATUS (status);
618         }
619
620         obj_desc = acpi_ns_get_attached_object (node);
621         if (!obj_desc) {
622                 return_ACPI_STATUS (AE_NOT_EXIST);
623         }
624
625         /* Resolve the operands */
626
627         status = acpi_ex_resolve_operands (op->common.aml_opcode,
628                           ACPI_WALK_OPERANDS, walk_state);
629
630         ACPI_DUMP_OPERANDS (ACPI_WALK_OPERANDS, ACPI_IMODE_EXECUTE,
631                           acpi_ps_get_opcode_name (op->common.aml_opcode),
632                           walk_state->num_operands, "after acpi_ex_resolve_operands");
633
634         if (ACPI_FAILURE (status)) {
635                 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "(%s) bad operand(s) (%X)\n",
636                         acpi_ps_get_opcode_name (op->common.aml_opcode), status));
637
638                 return_ACPI_STATUS (status);
639         }
640
641         /* Initialize the Buffer Field */
642
643         if (op->common.aml_opcode == AML_CREATE_FIELD_OP) {
644                 /* NOTE: Slightly different operands for this opcode */
645
646                 status = acpi_ds_init_buffer_field (op->common.aml_opcode, obj_desc,
647                                  walk_state->operands[0], walk_state->operands[1],
648                                  walk_state->operands[2], walk_state->operands[3]);
649         }
650         else {
651                 /* All other, create_xxx_field opcodes */
652
653                 status = acpi_ds_init_buffer_field (op->common.aml_opcode, obj_desc,
654                                  walk_state->operands[0], walk_state->operands[1],
655                                                   NULL, walk_state->operands[2]);
656         }
657
658         return_ACPI_STATUS (status);
659 }
660
661
662 /*****************************************************************************
663  *
664  * FUNCTION:    acpi_ds_eval_region_operands
665  *
666  * PARAMETERS:  walk_state      - Current walk
667  *              Op              - A valid region Op object
668  *
669  * RETURN:      Status
670  *
671  * DESCRIPTION: Get region address and length
672  *              Called from acpi_ds_exec_end_op during op_region parse tree walk
673  *
674  ****************************************************************************/
675
676 acpi_status
677 acpi_ds_eval_region_operands (
678         struct acpi_walk_state          *walk_state,
679         union acpi_parse_object         *op)
680 {
681         acpi_status                     status;
682         union acpi_operand_object       *obj_desc;
683         union acpi_operand_object       *operand_desc;
684         struct acpi_namespace_node      *node;
685         union acpi_parse_object         *next_op;
686
687
688         ACPI_FUNCTION_TRACE_PTR ("ds_eval_region_operands", op);
689
690
691         /*
692          * This is where we evaluate the address and length fields of the op_region declaration
693          */
694         node =  op->common.node;
695
696         /* next_op points to the op that holds the space_iD */
697
698         next_op = op->common.value.arg;
699
700         /* next_op points to address op */
701
702         next_op = next_op->common.next;
703
704         /* Evaluate/create the address and length operands */
705
706         status = acpi_ds_create_operands (walk_state, next_op);
707         if (ACPI_FAILURE (status)) {
708                 return_ACPI_STATUS (status);
709         }
710
711         /* Resolve the length and address operands to numbers */
712
713         status = acpi_ex_resolve_operands (op->common.aml_opcode, ACPI_WALK_OPERANDS, walk_state);
714         if (ACPI_FAILURE (status)) {
715                 return_ACPI_STATUS (status);
716         }
717
718         ACPI_DUMP_OPERANDS (ACPI_WALK_OPERANDS, ACPI_IMODE_EXECUTE,
719                           acpi_ps_get_opcode_name (op->common.aml_opcode),
720                           1, "after acpi_ex_resolve_operands");
721
722         obj_desc = acpi_ns_get_attached_object (node);
723         if (!obj_desc) {
724                 return_ACPI_STATUS (AE_NOT_EXIST);
725         }
726
727         /*
728          * Get the length operand and save it
729          * (at Top of stack)
730          */
731         operand_desc = walk_state->operands[walk_state->num_operands - 1];
732
733         obj_desc->region.length = (u32) operand_desc->integer.value;
734         acpi_ut_remove_reference (operand_desc);
735
736         /*
737          * Get the address and save it
738          * (at top of stack - 1)
739          */
740         operand_desc = walk_state->operands[walk_state->num_operands - 2];
741
742         obj_desc->region.address = (acpi_physical_address) operand_desc->integer.value;
743         acpi_ut_remove_reference (operand_desc);
744
745         ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "rgn_obj %p Addr %8.8X%8.8X Len %X\n",
746                 obj_desc,
747                 ACPI_FORMAT_UINT64 (obj_desc->region.address),
748                 obj_desc->region.length));
749
750         /* Now the address and length are valid for this opregion */
751
752         obj_desc->region.flags |= AOPOBJ_DATA_VALID;
753
754         return_ACPI_STATUS (status);
755 }
756
757
758 /*****************************************************************************
759  *
760  * FUNCTION:    acpi_ds_eval_data_object_operands
761  *
762  * PARAMETERS:  walk_state      - Current walk
763  *              Op              - A valid data_object Op object
764  *              obj_desc        - data_object
765  *
766  * RETURN:      Status
767  *
768  * DESCRIPTION: Get the operands and complete the following data objec types:
769  *              Buffer
770  *              Package
771  *
772  ****************************************************************************/
773
774 acpi_status
775 acpi_ds_eval_data_object_operands (
776         struct acpi_walk_state          *walk_state,
777         union acpi_parse_object         *op,
778         union acpi_operand_object       *obj_desc)
779 {
780         acpi_status                     status;
781         union acpi_operand_object       *arg_desc;
782         u32                             length;
783
784
785         ACPI_FUNCTION_TRACE ("ds_eval_data_object_operands");
786
787
788         /* The first operand (for all of these data objects) is the length */
789
790         status = acpi_ds_create_operand (walk_state, op->common.value.arg, 1);
791         if (ACPI_FAILURE (status)) {
792                 return_ACPI_STATUS (status);
793         }
794
795         status = acpi_ex_resolve_operands (walk_state->opcode,
796                           &(walk_state->operands [walk_state->num_operands -1]),
797                           walk_state);
798         if (ACPI_FAILURE (status)) {
799                 return_ACPI_STATUS (status);
800         }
801
802         /* Extract length operand */
803
804         arg_desc = walk_state->operands [walk_state->num_operands - 1];
805         length = (u32) arg_desc->integer.value;
806
807         /* Cleanup for length operand */
808
809         status = acpi_ds_obj_stack_pop (1, walk_state);
810         if (ACPI_FAILURE (status)) {
811                 return_ACPI_STATUS (status);
812         }
813
814         acpi_ut_remove_reference (arg_desc);
815
816         /*
817          * Create the actual data object
818          */
819         switch (op->common.aml_opcode) {
820         case AML_BUFFER_OP:
821
822                 status = acpi_ds_build_internal_buffer_obj (walk_state, op, length, &obj_desc);
823                 break;
824
825         case AML_PACKAGE_OP:
826         case AML_VAR_PACKAGE_OP:
827
828                 status = acpi_ds_build_internal_package_obj (walk_state, op, length, &obj_desc);
829                 break;
830
831         default:
832                 return_ACPI_STATUS (AE_AML_BAD_OPCODE);
833         }
834
835         if (ACPI_SUCCESS (status)) {
836                 /*
837                  * Return the object in the walk_state, unless the parent is a package --
838                  * in this case, the return object will be stored in the parse tree
839                  * for the package.
840                  */
841                 if ((!op->common.parent) ||
842                         ((op->common.parent->common.aml_opcode != AML_PACKAGE_OP) &&
843                          (op->common.parent->common.aml_opcode != AML_VAR_PACKAGE_OP) &&
844                          (op->common.parent->common.aml_opcode != AML_NAME_OP))) {
845                         walk_state->result_obj = obj_desc;
846                 }
847         }
848
849         return_ACPI_STATUS (status);
850 }
851
852
853 /*******************************************************************************
854  *
855  * FUNCTION:    acpi_ds_exec_begin_control_op
856  *
857  * PARAMETERS:  walk_list       - The list that owns the walk stack
858  *              Op              - The control Op
859  *
860  * RETURN:      Status
861  *
862  * DESCRIPTION: Handles all control ops encountered during control method
863  *              execution.
864  *
865  ******************************************************************************/
866
867 acpi_status
868 acpi_ds_exec_begin_control_op (
869         struct acpi_walk_state          *walk_state,
870         union acpi_parse_object         *op)
871 {
872         acpi_status                     status = AE_OK;
873         union acpi_generic_state        *control_state;
874
875
876         ACPI_FUNCTION_NAME ("ds_exec_begin_control_op");
877
878
879         ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Op=%p Opcode=%2.2X State=%p\n", op,
880                 op->common.aml_opcode, walk_state));
881
882         switch (op->common.aml_opcode) {
883         case AML_IF_OP:
884         case AML_WHILE_OP:
885
886                 /*
887                  * IF/WHILE: Create a new control state to manage these
888                  * constructs. We need to manage these as a stack, in order
889                  * to handle nesting.
890                  */
891                 control_state = acpi_ut_create_control_state ();
892                 if (!control_state) {
893                         status = AE_NO_MEMORY;
894                         break;
895                 }
896                 /*
897                  * Save a pointer to the predicate for multiple executions
898                  * of a loop
899                  */
900                 control_state->control.aml_predicate_start = walk_state->parser_state.aml - 1;
901                 control_state->control.package_end = walk_state->parser_state.pkg_end;
902                 control_state->control.opcode = op->common.aml_opcode;
903
904
905                 /* Push the control state on this walk's control stack */
906
907                 acpi_ut_push_generic_state (&walk_state->control_state, control_state);
908                 break;
909
910         case AML_ELSE_OP:
911
912                 /* Predicate is in the state object */
913                 /* If predicate is true, the IF was executed, ignore ELSE part */
914
915                 if (walk_state->last_predicate) {
916                         status = AE_CTRL_TRUE;
917                 }
918
919                 break;
920
921         case AML_RETURN_OP:
922
923                 break;
924
925         default:
926                 break;
927         }
928
929         return (status);
930 }
931
932
933 /*******************************************************************************
934  *
935  * FUNCTION:    acpi_ds_exec_end_control_op
936  *
937  * PARAMETERS:  walk_list       - The list that owns the walk stack
938  *              Op              - The control Op
939  *
940  * RETURN:      Status
941  *
942  * DESCRIPTION: Handles all control ops encountered during control method
943  *              execution.
944  *
945  ******************************************************************************/
946
947 acpi_status
948 acpi_ds_exec_end_control_op (
949         struct acpi_walk_state          *walk_state,
950         union acpi_parse_object         *op)
951 {
952         acpi_status                     status = AE_OK;
953         union acpi_generic_state        *control_state;
954
955
956         ACPI_FUNCTION_NAME ("ds_exec_end_control_op");
957
958
959         switch (op->common.aml_opcode) {
960         case AML_IF_OP:
961
962                 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "[IF_OP] Op=%p\n", op));
963
964                 /*
965                  * Save the result of the predicate in case there is an
966                  * ELSE to come
967                  */
968                 walk_state->last_predicate =
969                         (u8) walk_state->control_state->common.value;
970
971                 /*
972                  * Pop the control state that was created at the start
973                  * of the IF and free it
974                  */
975                 control_state = acpi_ut_pop_generic_state (&walk_state->control_state);
976                 acpi_ut_delete_generic_state (control_state);
977                 break;
978
979
980         case AML_ELSE_OP:
981
982                 break;
983
984
985         case AML_WHILE_OP:
986
987                 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "[WHILE_OP] Op=%p\n", op));
988
989                 if (walk_state->control_state->common.value) {
990                         /* Predicate was true, go back and evaluate it again! */
991
992                         status = AE_CTRL_PENDING;
993                 }
994
995                 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "[WHILE_OP] termination! Op=%p\n", op));
996
997                 /* Pop this control state and free it */
998
999                 control_state = acpi_ut_pop_generic_state (&walk_state->control_state);
1000
1001                 walk_state->aml_last_while = control_state->control.aml_predicate_start;
1002                 acpi_ut_delete_generic_state (control_state);
1003                 break;
1004
1005
1006         case AML_RETURN_OP:
1007
1008                 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
1009                         "[RETURN_OP] Op=%p Arg=%p\n",op, op->common.value.arg));
1010
1011                 /*
1012                  * One optional operand -- the return value
1013                  * It can be either an immediate operand or a result that
1014                  * has been bubbled up the tree
1015                  */
1016                 if (op->common.value.arg) {
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                         /*
1044                          * The return value has come from a previous calculation.
1045                          *
1046                          * If value being returned is a Reference (such as
1047                          * an arg or local), resolve it now because it may
1048                          * cease to exist at the end of the method.
1049                          *
1050                          * Allow references created by the Index operator to return unchanged.
1051                          */
1052                         if ((ACPI_GET_DESCRIPTOR_TYPE (walk_state->results->results.obj_desc[0]) == ACPI_DESC_TYPE_OPERAND) &&
1053                                 (ACPI_GET_OBJECT_TYPE (walk_state->results->results.obj_desc [0]) == ACPI_TYPE_LOCAL_REFERENCE) &&
1054                                 ((walk_state->results->results.obj_desc [0])->reference.opcode != AML_INDEX_OP)) {
1055                                 status = acpi_ex_resolve_to_value (&walk_state->results->results.obj_desc [0], walk_state);
1056                                 if (ACPI_FAILURE (status)) {
1057                                         return (status);
1058                                 }
1059                         }
1060
1061                         walk_state->return_desc = walk_state->results->results.obj_desc [0];
1062                 }
1063                 else {
1064                         /* No return operand */
1065
1066                         if (walk_state->num_operands) {
1067                                 acpi_ut_remove_reference (walk_state->operands [0]);
1068                         }
1069
1070                         walk_state->operands [0]    = NULL;
1071                         walk_state->num_operands    = 0;
1072                         walk_state->return_desc     = NULL;
1073                 }
1074
1075
1076                 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
1077                         "Completed RETURN_OP State=%p, ret_val=%p\n",
1078                         walk_state, walk_state->return_desc));
1079
1080                 /* End the control method execution right now */
1081
1082                 status = AE_CTRL_TERMINATE;
1083                 break;
1084
1085
1086         case AML_NOOP_OP:
1087
1088                 /* Just do nothing! */
1089                 break;
1090
1091
1092         case AML_BREAK_POINT_OP:
1093
1094                 /* Call up to the OS service layer to handle this */
1095
1096                 status = acpi_os_signal (ACPI_SIGNAL_BREAKPOINT, "Executed AML Breakpoint opcode");
1097
1098                 /* If and when it returns, all done. */
1099
1100                 break;
1101
1102
1103         case AML_BREAK_OP:
1104         case AML_CONTINUE_OP: /* ACPI 2.0 */
1105
1106
1107                 /* Pop and delete control states until we find a while */
1108
1109                 while (walk_state->control_state &&
1110                                 (walk_state->control_state->control.opcode != AML_WHILE_OP)) {
1111                         control_state = acpi_ut_pop_generic_state (&walk_state->control_state);
1112                         acpi_ut_delete_generic_state (control_state);
1113                 }
1114
1115                 /* No while found? */
1116
1117                 if (!walk_state->control_state) {
1118                         return (AE_AML_NO_WHILE);
1119                 }
1120
1121                 /* Was: walk_state->aml_last_while = walk_state->control_state->Control.aml_predicate_start; */
1122
1123                 walk_state->aml_last_while = walk_state->control_state->control.package_end;
1124
1125                 /* Return status depending on opcode */
1126
1127                 if (op->common.aml_opcode == AML_BREAK_OP) {
1128                         status = AE_CTRL_BREAK;
1129                 }
1130                 else {
1131                         status = AE_CTRL_CONTINUE;
1132                 }
1133                 break;
1134
1135
1136         default:
1137
1138                 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown control opcode=%X Op=%p\n",
1139                         op->common.aml_opcode, op));
1140
1141                 status = AE_AML_BAD_OPCODE;
1142                 break;
1143         }
1144
1145         return (status);
1146 }
1147