import of ftp.dlink.com/GPL/DSMG-600_reB/ppclinux.tar.gz
[linux-2.4.21-pre4.git] / drivers / acpi / dispatcher / dswexec.c
1 /******************************************************************************
2  *
3  * Module Name: dswexec - Dispatcher method execution callbacks;
4  *                        dispatch to interpreter.
5  *              $Revision: 1.1.1.1 $
6  *
7  *****************************************************************************/
8
9 /*
10  *  Copyright (C) 2000, 2001 R. Byron Moore
11  *
12  *  This program is free software; you can redistribute it and/or modify
13  *  it under the terms of the GNU General Public License as published by
14  *  the Free Software Foundation; either version 2 of the License, or
15  *  (at your option) any later version.
16  *
17  *  This program is distributed in the hope that it will be useful,
18  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
19  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  *  GNU General Public License for more details.
21  *
22  *  You should have received a copy of the GNU General Public License
23  *  along with this program; if not, write to the Free Software
24  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
25  */
26
27
28 #include "acpi.h"
29 #include "acparser.h"
30 #include "amlcode.h"
31 #include "acdispat.h"
32 #include "acinterp.h"
33 #include "acnamesp.h"
34 #include "acdebug.h"
35
36
37 #define _COMPONENT          ACPI_DISPATCHER
38          MODULE_NAME         ("dswexec")
39
40 /*
41  * Dispatch tables for opcode classes
42  */
43 ACPI_EXECUTE_OP         acpi_gbl_op_type_dispatch [] = {
44                          acpi_ex_opcode_1A_0T_0R,
45                          acpi_ex_opcode_1A_0T_1R,
46                          acpi_ex_opcode_1A_1T_0R,
47                          acpi_ex_opcode_1A_1T_1R,
48                          acpi_ex_opcode_2A_0T_0R,
49                          acpi_ex_opcode_2A_0T_1R,
50                          acpi_ex_opcode_2A_1T_1R,
51                          acpi_ex_opcode_2A_2T_1R,
52                          acpi_ex_opcode_3A_0T_0R,
53                          acpi_ex_opcode_3A_1T_1R,
54                          acpi_ex_opcode_6A_0T_1R};
55
56 /*****************************************************************************
57  *
58  * FUNCTION:    Acpi_ds_get_predicate_value
59  *
60  * PARAMETERS:  Walk_state      - Current state of the parse tree walk
61  *
62  * RETURN:      Status
63  *
64  * DESCRIPTION: Get the result of a predicate evaluation
65  *
66  ****************************************************************************/
67
68 acpi_status
69 acpi_ds_get_predicate_value (
70         acpi_walk_state         *walk_state,
71         u32                     has_result_obj) {
72         acpi_status             status = AE_OK;
73         acpi_operand_object     *obj_desc;
74
75
76         FUNCTION_TRACE_PTR ("Ds_get_predicate_value", walk_state);
77
78
79         walk_state->control_state->common.state = 0;
80
81         if (has_result_obj) {
82                 status = acpi_ds_result_pop (&obj_desc, walk_state);
83                 if (ACPI_FAILURE (status)) {
84                         ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
85                                 "Could not get result from predicate evaluation, %s\n",
86                                 acpi_format_exception (status)));
87
88                         return_ACPI_STATUS (status);
89                 }
90         }
91
92         else {
93                 status = acpi_ds_create_operand (walk_state, walk_state->op, 0);
94                 if (ACPI_FAILURE (status)) {
95                         return_ACPI_STATUS (status);
96                 }
97
98                 status = acpi_ex_resolve_to_value (&walk_state->operands [0], walk_state);
99                 if (ACPI_FAILURE (status)) {
100                         return_ACPI_STATUS (status);
101                 }
102
103                 obj_desc = walk_state->operands [0];
104         }
105
106         if (!obj_desc) {
107                 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "No predicate Obj_desc=%p State=%p\n",
108                         obj_desc, walk_state));
109
110                 return_ACPI_STATUS (AE_AML_NO_OPERAND);
111         }
112
113
114         /*
115          * Result of predicate evaluation currently must
116          * be a number
117          */
118         if (obj_desc->common.type != ACPI_TYPE_INTEGER) {
119                 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
120                         "Bad predicate (not a number) Obj_desc=%p State=%p Type=%X\n",
121                         obj_desc, walk_state, obj_desc->common.type));
122
123                 status = AE_AML_OPERAND_TYPE;
124                 goto cleanup;
125         }
126
127
128         /* Truncate the predicate to 32-bits if necessary */
129
130         acpi_ex_truncate_for32bit_table (obj_desc, walk_state);
131
132         /*
133          * Save the result of the predicate evaluation on
134          * the control stack
135          */
136         if (obj_desc->integer.value) {
137                 walk_state->control_state->common.value = TRUE;
138         }
139
140         else {
141                 /*
142                  * Predicate is FALSE, we will just toss the
143                  * rest of the package
144                  */
145                 walk_state->control_state->common.value = FALSE;
146                 status = AE_CTRL_FALSE;
147         }
148
149
150 cleanup:
151
152         ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Completed a predicate eval=%X Op=%pn",
153                 walk_state->control_state->common.value, walk_state->op));
154
155          /* Break to debugger to display result */
156
157         DEBUGGER_EXEC (acpi_db_display_result_object (obj_desc, walk_state));
158
159         /*
160          * Delete the predicate result object (we know that
161          * we don't need it anymore)
162          */
163         acpi_ut_remove_reference (obj_desc);
164
165         walk_state->control_state->common.state = CONTROL_NORMAL;
166         return_ACPI_STATUS (status);
167 }
168
169
170 /*****************************************************************************
171  *
172  * FUNCTION:    Acpi_ds_exec_begin_op
173  *
174  * PARAMETERS:  Walk_state      - Current state of the parse tree walk
175  *              Out_op          - Return op if a new one is created
176  *
177  * RETURN:      Status
178  *
179  * DESCRIPTION: Descending callback used during the execution of control
180  *              methods.  This is where most operators and operands are
181  *              dispatched to the interpreter.
182  *
183  ****************************************************************************/
184
185 acpi_status
186 acpi_ds_exec_begin_op (
187         acpi_walk_state         *walk_state,
188         acpi_parse_object       **out_op)
189 {
190         acpi_parse_object       *op;
191         acpi_status             status = AE_OK;
192         u32                     opcode_class;
193
194
195         FUNCTION_TRACE_PTR ("Ds_exec_begin_op", walk_state);
196
197
198         op = walk_state->op;
199         if (!op) {
200                 status = acpi_ds_load2_begin_op (walk_state, out_op);
201                 if (ACPI_FAILURE (status)) {
202                         return_ACPI_STATUS (status);
203                 }
204
205                 op = *out_op;
206                 walk_state->op = op;
207                 walk_state->op_info = acpi_ps_get_opcode_info (op->opcode);
208                 walk_state->opcode = op->opcode;
209         }
210
211         if (op == walk_state->origin) {
212                 if (out_op) {
213                         *out_op = op;
214                 }
215
216                 return_ACPI_STATUS (AE_OK);
217         }
218
219         /*
220          * If the previous opcode was a conditional, this opcode
221          * must be the beginning of the associated predicate.
222          * Save this knowledge in the current scope descriptor
223          */
224         if ((walk_state->control_state) &&
225                 (walk_state->control_state->common.state ==
226                         CONTROL_CONDITIONAL_EXECUTING)) {
227                 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Exec predicate Op=%p State=%p\n",
228                                   op, walk_state));
229
230                 walk_state->control_state->common.state = CONTROL_PREDICATE_EXECUTING;
231
232                 /* Save start of predicate */
233
234                 walk_state->control_state->control.predicate_op = op;
235         }
236
237
238         opcode_class = walk_state->op_info->class;
239
240         /* We want to send namepaths to the load code */
241
242         if (op->opcode == AML_INT_NAMEPATH_OP) {
243                 opcode_class = AML_CLASS_NAMED_OBJECT;
244         }
245
246         /*
247          * Handle the opcode based upon the opcode type
248          */
249         switch (opcode_class) {
250         case AML_CLASS_CONTROL:
251
252                 status = acpi_ds_result_stack_push (walk_state);
253                 if (ACPI_FAILURE (status)) {
254                         return_ACPI_STATUS (status);
255                 }
256
257                 status = acpi_ds_exec_begin_control_op (walk_state, op);
258                 break;
259
260
261         case AML_CLASS_NAMED_OBJECT:
262
263                 if (walk_state->walk_type == WALK_METHOD) {
264                         /*
265                          * Found a named object declaration during method
266                          * execution;  we must enter this object into the
267                          * namespace.  The created object is temporary and
268                          * will be deleted upon completion of the execution
269                          * of this method.
270                          */
271                         status = acpi_ds_load2_begin_op (walk_state, NULL);
272                 }
273
274
275                 if (op->opcode == AML_REGION_OP) {
276                         status = acpi_ds_result_stack_push (walk_state);
277                 }
278
279                 break;
280
281
282         /* most operators with arguments */
283
284         case AML_CLASS_EXECUTE:
285         case AML_CLASS_CREATE:
286
287                 /* Start a new result/operand state */
288
289                 status = acpi_ds_result_stack_push (walk_state);
290                 break;
291
292
293         default:
294                 break;
295         }
296
297         /* Nothing to do here during method execution */
298
299         return_ACPI_STATUS (status);
300 }
301
302
303 /*****************************************************************************
304  *
305  * FUNCTION:    Acpi_ds_exec_end_op
306  *
307  * PARAMETERS:  Walk_state      - Current state of the parse tree walk
308  *              Op              - Op that has been just been completed in the
309  *                                walk;  Arguments have now been evaluated.
310  *
311  * RETURN:      Status
312  *
313  * DESCRIPTION: Ascending callback used during the execution of control
314  *              methods.  The only thing we really need to do here is to
315  *              notice the beginning of IF, ELSE, and WHILE blocks.
316  *
317  ****************************************************************************/
318
319 acpi_status
320 acpi_ds_exec_end_op (
321         acpi_walk_state         *walk_state)
322 {
323         acpi_parse_object       *op;
324         acpi_status             status = AE_OK;
325         u32                     op_type;
326         u32                     op_class;
327         acpi_parse_object       *next_op;
328         acpi_parse_object       *first_arg;
329         u32                     i;
330
331
332         FUNCTION_TRACE_PTR ("Ds_exec_end_op", walk_state);
333
334
335         op      = walk_state->op;
336         op_type = walk_state->op_info->type;
337         op_class = walk_state->op_info->class;
338
339         if (op_class == AML_CLASS_UNKNOWN) {
340                 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown opcode %X\n", op->opcode));
341                 return_ACPI_STATUS (AE_NOT_IMPLEMENTED);
342         }
343
344         first_arg = op->value.arg;
345
346         /* Init the walk state */
347
348         walk_state->num_operands = 0;
349         walk_state->return_desc = NULL;
350         walk_state->result_obj = NULL;
351
352
353         /* Call debugger for single step support (DEBUG build only) */
354
355         DEBUGGER_EXEC (status = acpi_db_single_step (walk_state, op, op_class));
356         DEBUGGER_EXEC (if (ACPI_FAILURE (status)) {return_ACPI_STATUS (status);});
357
358
359         switch (op_class) {
360         /* Decode the Opcode Class */
361
362         case AML_CLASS_ARGUMENT: /* constants, literals, etc.  do nothing */
363                 break;
364
365         /* most operators with arguments */
366
367         case AML_CLASS_EXECUTE:
368
369                 /* Build resolved operand stack */
370
371                 status = acpi_ds_create_operands (walk_state, first_arg);
372                 if (ACPI_FAILURE (status)) {
373                         goto cleanup;
374                 }
375
376                 /* Done with this result state (Now that operand stack is built) */
377
378                 status = acpi_ds_result_stack_pop (walk_state);
379                 if (ACPI_FAILURE (status)) {
380                         goto cleanup;
381                 }
382
383                 /* Resolve all operands */
384
385                 status = acpi_ex_resolve_operands (walk_state->opcode,
386                                   &(walk_state->operands [walk_state->num_operands -1]),
387                                   walk_state);
388                 if (ACPI_FAILURE (status)) {
389                         /* TBD: must pop and delete operands */
390
391                         ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "[%s]: Could not resolve operands, %s\n",
392                                 acpi_ps_get_opcode_name (walk_state->opcode), acpi_format_exception (status)));
393
394                         /*
395                          * On error, we must delete all the operands and clear the
396                          * operand stack
397                          */
398                         for (i = 0; i < walk_state->num_operands; i++) {
399                                 acpi_ut_remove_reference (walk_state->operands[i]);
400                                 walk_state->operands[i] = NULL;
401                         }
402
403                         walk_state->num_operands = 0;
404                         goto cleanup;
405                 }
406
407                 DUMP_OPERANDS (WALK_OPERANDS, IMODE_EXECUTE, acpi_ps_get_opcode_name (walk_state->opcode),
408                                   walk_state->num_operands, "after Ex_resolve_operands");
409
410                 /*
411                  * Dispatch the request to the appropriate interpreter handler
412                  * routine.  There is one routine per opcode "type" based upon the
413                  * number of opcode arguments and return type.
414                  */
415                 status = acpi_gbl_op_type_dispatch [op_type] (walk_state);
416
417
418                 /* Delete argument objects and clear the operand stack */
419
420                 for (i = 0; i < walk_state->num_operands; i++) {
421                         /*
422                          * Remove a reference to all operands, including both
423                          * "Arguments" and "Targets".
424                          */
425                         acpi_ut_remove_reference (walk_state->operands[i]);
426                         walk_state->operands[i] = NULL;
427                 }
428
429                 walk_state->num_operands = 0;
430
431                 /*
432                  * If a result object was returned from above, push it on the
433                  * current result stack
434                  */
435                 if (ACPI_SUCCESS (status) &&
436                         walk_state->result_obj) {
437                         status = acpi_ds_result_push (walk_state->result_obj, walk_state);
438                 }
439
440                 break;
441
442
443         default:
444
445                 switch (op_type) {
446                 case AML_TYPE_CONTROL:    /* Type 1 opcode, IF/ELSE/WHILE/NOOP */
447
448                         /* 1 Operand, 0 External_result, 0 Internal_result */
449
450                         status = acpi_ds_exec_end_control_op (walk_state, op);
451
452                         acpi_ds_result_stack_pop (walk_state);
453                         break;
454
455
456                 case AML_TYPE_METHOD_CALL:
457
458                         ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Method invocation, Op=%p\n", op));
459
460                         /*
461                          * (AML_METHODCALL) Op->Value->Arg->Node contains
462                          * the method Node pointer
463                          */
464                         /* Next_op points to the op that holds the method name */
465
466                         next_op = first_arg;
467
468                         /* Next_op points to first argument op */
469
470                         next_op = next_op->next;
471
472                         /*
473                          * Get the method's arguments and put them on the operand stack
474                          */
475                         status = acpi_ds_create_operands (walk_state, next_op);
476                         if (ACPI_FAILURE (status)) {
477                                 break;
478                         }
479
480                         /*
481                          * Since the operands will be passed to another
482                          * control method, we must resolve all local
483                          * references here (Local variables, arguments
484                          * to *this* method, etc.)
485                          */
486                         status = acpi_ds_resolve_operands (walk_state);
487                         if (ACPI_FAILURE (status)) {
488                                 break;
489                         }
490
491                         /*
492                          * Tell the walk loop to preempt this running method and
493                          * execute the new method
494                          */
495                         status = AE_CTRL_TRANSFER;
496
497                         /*
498                          * Return now; we don't want to disturb anything,
499                          * especially the operand count!
500                          */
501                         return_ACPI_STATUS (status);
502                         break;
503
504
505                 case AML_TYPE_CREATE_FIELD:
506
507                         ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
508                                 "Executing Create_field Buffer/Index Op=%p\n", op));
509
510                         status = acpi_ds_load2_end_op (walk_state);
511                         if (ACPI_FAILURE (status)) {
512                                 break;
513                         }
514
515                         status = acpi_ds_eval_buffer_field_operands (walk_state, op);
516                         break;
517
518
519                 case AML_TYPE_NAMED_FIELD:
520                 case AML_TYPE_NAMED_COMPLEX:
521                 case AML_TYPE_NAMED_SIMPLE:
522
523                         status = acpi_ds_load2_end_op (walk_state);
524                         if (ACPI_FAILURE (status)) {
525                                 break;
526                         }
527
528                         if (op->opcode == AML_REGION_OP) {
529                                 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
530                                         "Executing Op_region Address/Length Op=%p\n", op));
531
532                                 status = acpi_ds_eval_region_operands (walk_state, op);
533                                 if (ACPI_FAILURE (status)) {
534                                         break;
535                                 }
536
537                                 status = acpi_ds_result_stack_pop (walk_state);
538                         }
539
540                         break;
541
542                 case AML_TYPE_UNDEFINED:
543
544                         ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Undefined opcode type Op=%p\n", op));
545                         return_ACPI_STATUS (AE_NOT_IMPLEMENTED);
546                         break;
547
548
549                 case AML_TYPE_BOGUS:
550                         ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Internal opcode=%X type Op=%p\n",
551                                 walk_state->opcode, op));
552                         break;
553
554                 default:
555
556                         ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
557                                 "Unimplemented opcode, class=%X type=%X Opcode=%X Op=%p\n",
558                                 op_class, op_type, op->opcode, op));
559
560                         status = AE_NOT_IMPLEMENTED;
561                         break;
562                 }
563         }
564
565         /*
566          * ACPI 2.0 support for 64-bit integers:
567          * Truncate numeric result value if we are executing from a 32-bit ACPI table
568          */
569         acpi_ex_truncate_for32bit_table (walk_state->result_obj, walk_state);
570
571         /*
572          * Check if we just completed the evaluation of a
573          * conditional predicate
574          */
575
576         if ((walk_state->control_state) &&
577                 (walk_state->control_state->common.state ==
578                         CONTROL_PREDICATE_EXECUTING) &&
579                 (walk_state->control_state->control.predicate_op == op)) {
580                 status = acpi_ds_get_predicate_value (walk_state, !! walk_state->result_obj);
581                 walk_state->result_obj = NULL;
582         }
583
584
585 cleanup:
586         if (walk_state->result_obj) {
587                 /* Break to debugger to display result */
588
589                 DEBUGGER_EXEC (acpi_db_display_result_object (walk_state->result_obj, walk_state));
590
591                 /*
592                  * Delete the result op if and only if:
593                  * Parent will not use the result -- such as any
594                  * non-nested type2 op in a method (parent will be method)
595                  */
596                 acpi_ds_delete_result_if_not_used (op, walk_state->result_obj, walk_state);
597         }
598
599         /* Always clear the object stack */
600
601         /* TBD: [Investigate] Clear stack of return value,
602         but don't delete it */
603         walk_state->num_operands = 0;
604
605         return_ACPI_STATUS (status);
606 }
607
608