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