dswexec.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:15k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

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