Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
dswexec.c
Go to the documentation of this file.
1 /******************************************************************************
2  *
3  * Module Name: dswexec - Dispatcher method execution callbacks;
4  * dispatch to interpreter.
5  *
6  *****************************************************************************/
7 
8 /*
9  * Copyright (C) 2000 - 2012, Intel Corp.
10  * All rights reserved.
11  *
12  * Redistribution and use in source and binary forms, with or without
13  * modification, are permitted provided that the following conditions
14  * are met:
15  * 1. Redistributions of source code must retain the above copyright
16  * notice, this list of conditions, and the following disclaimer,
17  * without modification.
18  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
19  * substantially similar to the "NO WARRANTY" disclaimer below
20  * ("Disclaimer") and any redistribution must be conditioned upon
21  * including a substantially similar Disclaimer requirement for further
22  * binary redistribution.
23  * 3. Neither the names of the above-listed copyright holders nor the names
24  * of any contributors may be used to endorse or promote products derived
25  * from this software without specific prior written permission.
26  *
27  * Alternatively, this software may be distributed under the terms of the
28  * GNU General Public License ("GPL") version 2 as published by the Free
29  * Software Foundation.
30  *
31  * NO WARRANTY
32  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
33  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
34  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
35  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
36  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
38  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
40  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
41  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
42  * POSSIBILITY OF SUCH DAMAGES.
43  */
44 
45 #include <acpi/acpi.h>
46 #include "accommon.h"
47 #include "acparser.h"
48 #include "amlcode.h"
49 #include "acdispat.h"
50 #include "acinterp.h"
51 #include "acnamesp.h"
52 #include "acdebug.h"
53 
54 #define _COMPONENT ACPI_DISPATCHER
55 ACPI_MODULE_NAME("dswexec")
56 
57 /*
58  * Dispatch table for opcode classes
59  */
60 static ACPI_EXECUTE_OP acpi_gbl_op_type_dispatch[] = {
73 };
74 
75 /*****************************************************************************
76  *
77  * FUNCTION: acpi_ds_get_predicate_value
78  *
79  * PARAMETERS: walk_state - Current state of the parse tree walk
80  * result_obj - if non-zero, pop result from result stack
81  *
82  * RETURN: Status
83  *
84  * DESCRIPTION: Get the result of a predicate evaluation
85  *
86  ****************************************************************************/
87 
90  union acpi_operand_object *result_obj)
91 {
93  union acpi_operand_object *obj_desc;
94  union acpi_operand_object *local_obj_desc = NULL;
95 
96  ACPI_FUNCTION_TRACE_PTR(ds_get_predicate_value, walk_state);
97 
98  walk_state->control_state->common.state = 0;
99 
100  if (result_obj) {
101  status = acpi_ds_result_pop(&obj_desc, walk_state);
102  if (ACPI_FAILURE(status)) {
103  ACPI_EXCEPTION((AE_INFO, status,
104  "Could not get result from predicate evaluation"));
105 
106  return_ACPI_STATUS(status);
107  }
108  } else {
109  status = acpi_ds_create_operand(walk_state, walk_state->op, 0);
110  if (ACPI_FAILURE(status)) {
111  return_ACPI_STATUS(status);
112  }
113 
114  status =
115  acpi_ex_resolve_to_value(&walk_state->operands[0],
116  walk_state);
117  if (ACPI_FAILURE(status)) {
118  return_ACPI_STATUS(status);
119  }
120 
121  obj_desc = walk_state->operands[0];
122  }
123 
124  if (!obj_desc) {
126  "No predicate ObjDesc=%p State=%p",
127  obj_desc, walk_state));
128 
130  }
131 
132  /*
133  * Result of predicate evaluation must be an Integer
134  * object. Implicitly convert the argument if necessary.
135  */
136  status = acpi_ex_convert_to_integer(obj_desc, &local_obj_desc, 16);
137  if (ACPI_FAILURE(status)) {
138  goto cleanup;
139  }
140 
141  if (local_obj_desc->common.type != ACPI_TYPE_INTEGER) {
143  "Bad predicate (not an integer) ObjDesc=%p State=%p Type=0x%X",
144  obj_desc, walk_state, obj_desc->common.type));
145 
146  status = AE_AML_OPERAND_TYPE;
147  goto cleanup;
148  }
149 
150  /* Truncate the predicate to 32-bits if necessary */
151 
152  acpi_ex_truncate_for32bit_table(local_obj_desc);
153 
154  /*
155  * Save the result of the predicate evaluation on
156  * the control stack
157  */
158  if (local_obj_desc->integer.value) {
159  walk_state->control_state->common.value = TRUE;
160  } else {
161  /*
162  * Predicate is FALSE, we will just toss the
163  * rest of the package
164  */
165  walk_state->control_state->common.value = FALSE;
166  status = AE_CTRL_FALSE;
167  }
168 
169  /* Predicate can be used for an implicit return value */
170 
171  (void)acpi_ds_do_implicit_return(local_obj_desc, walk_state, TRUE);
172 
173  cleanup:
174 
175  ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Completed a predicate eval=%X Op=%p\n",
176  walk_state->control_state->common.value,
177  walk_state->op));
178 
179  /* Break to debugger to display result */
180 
182  (local_obj_desc, walk_state));
183 
184  /*
185  * Delete the predicate result object (we know that
186  * we don't need it anymore)
187  */
188  if (local_obj_desc != obj_desc) {
189  acpi_ut_remove_reference(local_obj_desc);
190  }
191  acpi_ut_remove_reference(obj_desc);
192 
193  walk_state->control_state->common.state = ACPI_CONTROL_NORMAL;
194  return_ACPI_STATUS(status);
195 }
196 
197 /*****************************************************************************
198  *
199  * FUNCTION: acpi_ds_exec_begin_op
200  *
201  * PARAMETERS: walk_state - Current state of the parse tree walk
202  * out_op - Where to return op if a new one is created
203  *
204  * RETURN: Status
205  *
206  * DESCRIPTION: Descending callback used during the execution of control
207  * methods. This is where most operators and operands are
208  * dispatched to the interpreter.
209  *
210  ****************************************************************************/
211 
214  union acpi_parse_object **out_op)
215 {
216  union acpi_parse_object *op;
218  u32 opcode_class;
219 
220  ACPI_FUNCTION_TRACE_PTR(ds_exec_begin_op, walk_state);
221 
222  op = walk_state->op;
223  if (!op) {
224  status = acpi_ds_load2_begin_op(walk_state, out_op);
225  if (ACPI_FAILURE(status)) {
226  goto error_exit;
227  }
228 
229  op = *out_op;
230  walk_state->op = op;
231  walk_state->opcode = op->common.aml_opcode;
232  walk_state->op_info =
233  acpi_ps_get_opcode_info(op->common.aml_opcode);
234 
235  if (acpi_ns_opens_scope(walk_state->op_info->object_type)) {
237  "(%s) Popping scope for Op %p\n",
238  acpi_ut_get_type_name(walk_state->
239  op_info->
240  object_type),
241  op));
242 
243  status = acpi_ds_scope_stack_pop(walk_state);
244  if (ACPI_FAILURE(status)) {
245  goto error_exit;
246  }
247  }
248  }
249 
250  if (op == walk_state->origin) {
251  if (out_op) {
252  *out_op = op;
253  }
254 
256  }
257 
258  /*
259  * If the previous opcode was a conditional, this opcode
260  * must be the beginning of the associated predicate.
261  * Save this knowledge in the current scope descriptor
262  */
263  if ((walk_state->control_state) &&
264  (walk_state->control_state->common.state ==
267  "Exec predicate Op=%p State=%p\n", op,
268  walk_state));
269 
270  walk_state->control_state->common.state =
272 
273  /* Save start of predicate */
274 
275  walk_state->control_state->control.predicate_op = op;
276  }
277 
278  opcode_class = walk_state->op_info->class;
279 
280  /* We want to send namepaths to the load code */
281 
282  if (op->common.aml_opcode == AML_INT_NAMEPATH_OP) {
283  opcode_class = AML_CLASS_NAMED_OBJECT;
284  }
285 
286  /*
287  * Handle the opcode based upon the opcode type
288  */
289  switch (opcode_class) {
290  case AML_CLASS_CONTROL:
291 
292  status = acpi_ds_exec_begin_control_op(walk_state, op);
293  break;
294 
296 
297  if (walk_state->walk_type & ACPI_WALK_METHOD) {
298  /*
299  * Found a named object declaration during method execution;
300  * we must enter this object into the namespace. The created
301  * object is temporary and will be deleted upon completion of
302  * the execution of this method.
303  *
304  * Note 10/2010: Except for the Scope() op. This opcode does
305  * not actually create a new object, it refers to an existing
306  * object. However, for Scope(), we want to indeed open a
307  * new scope.
308  */
309  if (op->common.aml_opcode != AML_SCOPE_OP) {
310  status =
311  acpi_ds_load2_begin_op(walk_state, NULL);
312  } else {
313  status =
315  op->named.node->
316  type, walk_state);
317  if (ACPI_FAILURE(status)) {
318  return_ACPI_STATUS(status);
319  }
320  }
321  }
322  break;
323 
324  case AML_CLASS_EXECUTE:
325  case AML_CLASS_CREATE:
326 
327  break;
328 
329  default:
330  break;
331  }
332 
333  /* Nothing to do here during method execution */
334 
335  return_ACPI_STATUS(status);
336 
337  error_exit:
338  status = acpi_ds_method_error(status, walk_state);
339  return_ACPI_STATUS(status);
340 }
341 
342 /*****************************************************************************
343  *
344  * FUNCTION: acpi_ds_exec_end_op
345  *
346  * PARAMETERS: walk_state - Current state of the parse tree walk
347  *
348  * RETURN: Status
349  *
350  * DESCRIPTION: Ascending callback used during the execution of control
351  * methods. The only thing we really need to do here is to
352  * notice the beginning of IF, ELSE, and WHILE blocks.
353  *
354  ****************************************************************************/
355 
357 {
358  union acpi_parse_object *op;
360  u32 op_type;
361  u32 op_class;
362  union acpi_parse_object *next_op;
363  union acpi_parse_object *first_arg;
364 
365  ACPI_FUNCTION_TRACE_PTR(ds_exec_end_op, walk_state);
366 
367  op = walk_state->op;
368  op_type = walk_state->op_info->type;
369  op_class = walk_state->op_info->class;
370 
371  if (op_class == AML_CLASS_UNKNOWN) {
372  ACPI_ERROR((AE_INFO, "Unknown opcode 0x%X",
373  op->common.aml_opcode));
375  }
376 
377  first_arg = op->common.value.arg;
378 
379  /* Init the walk state */
380 
381  walk_state->num_operands = 0;
382  walk_state->operand_index = 0;
383  walk_state->return_desc = NULL;
384  walk_state->result_obj = NULL;
385 
386  /* Call debugger for single step support (DEBUG build only) */
387 
388  ACPI_DEBUGGER_EXEC(status =
389  acpi_db_single_step(walk_state, op, op_class));
390  ACPI_DEBUGGER_EXEC(if (ACPI_FAILURE(status)) {
391  return_ACPI_STATUS(status);}
392  ) ;
393 
394  /* Decode the Opcode Class */
395 
396  switch (op_class) {
397  case AML_CLASS_ARGUMENT: /* Constants, literals, etc. */
398 
399  if (walk_state->opcode == AML_INT_NAMEPATH_OP) {
400  status = acpi_ds_evaluate_name_path(walk_state);
401  if (ACPI_FAILURE(status)) {
402  goto cleanup;
403  }
404  }
405  break;
406 
407  case AML_CLASS_EXECUTE: /* Most operators with arguments */
408 
409  /* Build resolved operand stack */
410 
411  status = acpi_ds_create_operands(walk_state, first_arg);
412  if (ACPI_FAILURE(status)) {
413  goto cleanup;
414  }
415 
416  /*
417  * All opcodes require operand resolution, with the only exceptions
418  * being the object_type and size_of operators.
419  */
420  if (!(walk_state->op_info->flags & AML_NO_OPERAND_RESOLVE)) {
421 
422  /* Resolve all operands */
423 
424  status = acpi_ex_resolve_operands(walk_state->opcode,
425  &(walk_state->
426  operands
427  [walk_state->
428  num_operands - 1]),
429  walk_state);
430  }
431 
432  if (ACPI_SUCCESS(status)) {
433  /*
434  * Dispatch the request to the appropriate interpreter handler
435  * routine. There is one routine per opcode "type" based upon the
436  * number of opcode arguments and return type.
437  */
438  status =
439  acpi_gbl_op_type_dispatch[op_type] (walk_state);
440  } else {
441  /*
442  * Treat constructs of the form "Store(LocalX,LocalX)" as noops when the
443  * Local is uninitialized.
444  */
445  if ((status == AE_AML_UNINITIALIZED_LOCAL) &&
446  (walk_state->opcode == AML_STORE_OP) &&
447  (walk_state->operands[0]->common.type ==
449  && (walk_state->operands[1]->common.type ==
451  && (walk_state->operands[0]->reference.class ==
452  walk_state->operands[1]->reference.class)
453  && (walk_state->operands[0]->reference.value ==
454  walk_state->operands[1]->reference.value)) {
455  status = AE_OK;
456  } else {
457  ACPI_EXCEPTION((AE_INFO, status,
458  "While resolving operands for [%s]",
460  (walk_state->opcode)));
461  }
462  }
463 
464  /* Always delete the argument objects and clear the operand stack */
465 
466  acpi_ds_clear_operands(walk_state);
467 
468  /*
469  * If a result object was returned from above, push it on the
470  * current result stack
471  */
472  if (ACPI_SUCCESS(status) && walk_state->result_obj) {
473  status =
474  acpi_ds_result_push(walk_state->result_obj,
475  walk_state);
476  }
477  break;
478 
479  default:
480 
481  switch (op_type) {
482  case AML_TYPE_CONTROL: /* Type 1 opcode, IF/ELSE/WHILE/NOOP */
483 
484  /* 1 Operand, 0 external_result, 0 internal_result */
485 
486  status = acpi_ds_exec_end_control_op(walk_state, op);
487 
488  break;
489 
491 
492  /*
493  * If the method is referenced from within a package
494  * declaration, it is not a invocation of the method, just
495  * a reference to it.
496  */
497  if ((op->asl.parent) &&
498  ((op->asl.parent->asl.aml_opcode == AML_PACKAGE_OP)
499  || (op->asl.parent->asl.aml_opcode ==
500  AML_VAR_PACKAGE_OP))) {
502  "Method Reference in a Package, Op=%p\n",
503  op));
504 
505  op->common.node =
506  (struct acpi_namespace_node *)op->asl.value.
507  arg->asl.node;
508  acpi_ut_add_reference(op->asl.value.arg->asl.
509  node->object);
511  }
512 
514  "Method invocation, Op=%p\n", op));
515 
516  /*
517  * (AML_METHODCALL) Op->Asl.Value.Arg->Asl.Node contains
518  * the method Node pointer
519  */
520  /* next_op points to the op that holds the method name */
521 
522  next_op = first_arg;
523 
524  /* next_op points to first argument op */
525 
526  next_op = next_op->common.next;
527 
528  /*
529  * Get the method's arguments and put them on the operand stack
530  */
531  status = acpi_ds_create_operands(walk_state, next_op);
532  if (ACPI_FAILURE(status)) {
533  break;
534  }
535 
536  /*
537  * Since the operands will be passed to another control method,
538  * we must resolve all local references here (Local variables,
539  * arguments to *this* method, etc.)
540  */
541  status = acpi_ds_resolve_operands(walk_state);
542  if (ACPI_FAILURE(status)) {
543 
544  /* On error, clear all resolved operands */
545 
546  acpi_ds_clear_operands(walk_state);
547  break;
548  }
549 
550  /*
551  * Tell the walk loop to preempt this running method and
552  * execute the new method
553  */
554  status = AE_CTRL_TRANSFER;
555 
556  /*
557  * Return now; we don't want to disturb anything,
558  * especially the operand count!
559  */
560  return_ACPI_STATUS(status);
561 
563 
565  "Executing CreateField Buffer/Index Op=%p\n",
566  op));
567 
568  status = acpi_ds_load2_end_op(walk_state);
569  if (ACPI_FAILURE(status)) {
570  break;
571  }
572 
573  status =
574  acpi_ds_eval_buffer_field_operands(walk_state, op);
575  break;
576 
578 
580  "Executing CreateObject (Buffer/Package) Op=%p\n",
581  op));
582 
583  switch (op->common.parent->common.aml_opcode) {
584  case AML_NAME_OP:
585 
586  /*
587  * Put the Node on the object stack (Contains the ACPI Name
588  * of this object)
589  */
590  walk_state->operands[0] =
591  (void *)op->common.parent->common.node;
592  walk_state->num_operands = 1;
593 
594  status = acpi_ds_create_node(walk_state,
595  op->common.parent->
596  common.node,
597  op->common.parent);
598  if (ACPI_FAILURE(status)) {
599  break;
600  }
601 
602  /* Fall through */
603  /*lint -fallthrough */
604 
606 
607  status =
609  (walk_state, op,
611  parent->common.
612  node));
613  break;
614 
615  default:
616 
617  status =
619  (walk_state, op, NULL);
620  break;
621  }
622 
623  /*
624  * If a result object was returned from above, push it on the
625  * current result stack
626  */
627  if (walk_state->result_obj) {
628  status =
629  acpi_ds_result_push(walk_state->result_obj,
630  walk_state);
631  }
632  break;
633 
638 
639  status = acpi_ds_load2_end_op(walk_state);
640  if (ACPI_FAILURE(status)) {
641  break;
642  }
643 
644  if (op->common.aml_opcode == AML_REGION_OP) {
646  "Executing OpRegion Address/Length Op=%p\n",
647  op));
648 
649  status =
650  acpi_ds_eval_region_operands(walk_state,
651  op);
652  if (ACPI_FAILURE(status)) {
653  break;
654  }
655  } else if (op->common.aml_opcode == AML_DATA_REGION_OP) {
657  "Executing DataTableRegion Strings Op=%p\n",
658  op));
659 
660  status =
662  (walk_state, op);
663  if (ACPI_FAILURE(status)) {
664  break;
665  }
666  } else if (op->common.aml_opcode == AML_BANK_FIELD_OP) {
668  "Executing BankField Op=%p\n",
669  op));
670 
671  status =
673  op);
674  if (ACPI_FAILURE(status)) {
675  break;
676  }
677  }
678  break;
679 
680  case AML_TYPE_UNDEFINED:
681 
683  "Undefined opcode type Op=%p", op));
685 
686  case AML_TYPE_BOGUS:
687 
689  "Internal opcode=%X type Op=%p\n",
690  walk_state->opcode, op));
691  break;
692 
693  default:
694 
696  "Unimplemented opcode, class=0x%X type=0x%X Opcode=-0x%X Op=%p",
697  op_class, op_type, op->common.aml_opcode,
698  op));
699 
700  status = AE_NOT_IMPLEMENTED;
701  break;
702  }
703  }
704 
705  /*
706  * ACPI 2.0 support for 64-bit integers: Truncate numeric
707  * result value if we are executing from a 32-bit ACPI table
708  */
710 
711  /*
712  * Check if we just completed the evaluation of a
713  * conditional predicate
714  */
715  if ((ACPI_SUCCESS(status)) &&
716  (walk_state->control_state) &&
717  (walk_state->control_state->common.state ==
719  (walk_state->control_state->control.predicate_op == op)) {
720  status =
721  acpi_ds_get_predicate_value(walk_state,
722  walk_state->result_obj);
723  walk_state->result_obj = NULL;
724  }
725 
726  cleanup:
727 
728  if (walk_state->result_obj) {
729 
730  /* Break to debugger to display result */
731 
733  (walk_state->result_obj, walk_state));
734 
735  /*
736  * Delete the result op if and only if:
737  * Parent will not use the result -- such as any
738  * non-nested type2 op in a method (parent will be method)
739  */
741  walk_state);
742  }
743 #ifdef _UNDER_DEVELOPMENT
744 
745  if (walk_state->parser_state.aml == walk_state->parser_state.aml_end) {
746  acpi_db_method_end(walk_state);
747  }
748 #endif
749 
750  /* Invoke exception handler on error */
751 
752  if (ACPI_FAILURE(status)) {
753  status = acpi_ds_method_error(status, walk_state);
754  }
755 
756  /* Always clear the object stack */
757 
758  walk_state->num_operands = 0;
759  return_ACPI_STATUS(status);
760 }