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

嵌入式Linux

开发平台:

Unix_Linux

  1. /******************************************************************************
  2.  *
  3.  * Module Name: psparse - Parser top level AML parse routines
  4.  *              $Revision: 104 $
  5.  *
  6.  *****************************************************************************/
  7. /*
  8.  *  Copyright (C) 2000, 2001 R. Byron Moore
  9.  *
  10.  *  This program is free software; you can redistribute it and/or modify
  11.  *  it under the terms of the GNU General Public License as published by
  12.  *  the Free Software Foundation; either version 2 of the License, or
  13.  *  (at your option) any later version.
  14.  *
  15.  *  This program is distributed in the hope that it will be useful,
  16.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  17.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18.  *  GNU General Public License for more details.
  19.  *
  20.  *  You should have received a copy of the GNU General Public License
  21.  *  along with this program; if not, write to the Free Software
  22.  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  23.  */
  24. /*
  25.  * Parse the AML and build an operation tree as most interpreters,
  26.  * like Perl, do.  Parsing is done by hand rather than with a YACC
  27.  * generated parser to tightly constrain stack and dynamic memory
  28.  * usage.  At the same time, parsing is kept flexible and the code
  29.  * fairly compact by parsing based on a list of AML opcode
  30.  * templates in Aml_op_info[]
  31.  */
  32. #include "acpi.h"
  33. #include "acparser.h"
  34. #include "acdispat.h"
  35. #include "amlcode.h"
  36. #include "acnamesp.h"
  37. #include "acdebug.h"
  38. #include "acinterp.h"
  39. #define _COMPONENT          ACPI_PARSER
  40.  MODULE_NAME         ("psparse")
  41. u32                         acpi_gbl_depth = 0;
  42. extern u32                  acpi_gbl_scope_depth;
  43. /*******************************************************************************
  44.  *
  45.  * FUNCTION:    Acpi_ps_get_opcode_size
  46.  *
  47.  * PARAMETERS:  Opcode          - An AML opcode
  48.  *
  49.  * RETURN:      Size of the opcode, in bytes (1 or 2)
  50.  *
  51.  * DESCRIPTION: Get the size of the current opcode.
  52.  *
  53.  ******************************************************************************/
  54. static u32
  55. acpi_ps_get_opcode_size (
  56. u32                     opcode)
  57. {
  58. /* Extended (2-byte) opcode if > 255 */
  59. if (opcode > 0x00FF) {
  60. return (2);
  61. }
  62. /* Otherwise, just a single byte opcode */
  63. return (1);
  64. }
  65. /*******************************************************************************
  66.  *
  67.  * FUNCTION:    Acpi_ps_peek_opcode
  68.  *
  69.  * PARAMETERS:  Parser_state        - A parser state object
  70.  *
  71.  * RETURN:      Status
  72.  *
  73.  * DESCRIPTION: Get next AML opcode (without incrementing AML pointer)
  74.  *
  75.  ******************************************************************************/
  76. u16
  77. acpi_ps_peek_opcode (
  78. acpi_parse_state        *parser_state)
  79. {
  80. u8                      *aml;
  81. u16                     opcode;
  82. aml = parser_state->aml;
  83. opcode = (u16) GET8 (aml);
  84. aml++;
  85. /*
  86.  * Original code special cased LNOTEQUAL, LLESSEQUAL, LGREATEREQUAL.
  87.  * These opcodes are no longer recognized. Instead, they are broken into
  88.  * two opcodes.
  89.  *
  90.  *
  91.  *    if (Opcode == AML_EXTOP
  92.  *       || (Opcode == AML_LNOT
  93.  *          && (GET8 (Aml) == AML_LEQUAL
  94.  *               || GET8 (Aml) == AML_LGREATER
  95.  *               || GET8 (Aml) == AML_LLESS)))
  96.  *
  97.  *     extended Opcode, !=, <=, or >=
  98.  */
  99. if (opcode == AML_EXTOP) {
  100. /* Extended opcode */
  101. opcode = (u16) ((opcode << 8) | GET8 (aml));
  102. }
  103. return (opcode);
  104. }
  105. /*******************************************************************************
  106.  *
  107.  * FUNCTION:    Acpi_ps_find_object
  108.  *
  109.  * PARAMETERS:  Opcode          - Current opcode
  110.  *              Parser_state    - Current state
  111.  *              Walk_state      - Current state
  112.  *              *Op             - Where found/new op is returned
  113.  *
  114.  * RETURN:      Status
  115.  *
  116.  * DESCRIPTION: Find a named object.  Two versions - one to search the parse
  117.  *              tree (for parser-only applications such as acpidump), another
  118.  *              to search the ACPI internal namespace (the parse tree may no
  119.  *              longer exist)
  120.  *
  121.  ******************************************************************************/
  122. #ifdef PARSER_ONLY
  123. acpi_status
  124. acpi_ps_find_object (
  125. acpi_walk_state         *walk_state,
  126. acpi_parse_object       **out_op)
  127. {
  128. NATIVE_CHAR             *path;
  129. /* We are only interested in opcodes that have an associated name */
  130. if (!(walk_state->op_info->flags & AML_NAMED)) {
  131. *out_op = walk_state->op;
  132. return (AE_OK);
  133. }
  134. /* Find the name in the parse tree */
  135. path = acpi_ps_get_next_namestring (&walk_state->parser_state);
  136. *out_op = acpi_ps_find (acpi_ps_get_parent_scope (&walk_state->parser_state),
  137.   path, walk_state->opcode, 1);
  138. if (!(*out_op)) {
  139. return (AE_NOT_FOUND);
  140. }
  141. return (AE_OK);
  142. }
  143. #endif
  144. /*******************************************************************************
  145.  *
  146.  * FUNCTION:    Acpi_ps_complete_this_op
  147.  *
  148.  * PARAMETERS:  Walk_state      - Current State
  149.  *              Op              - Op to complete
  150.  *
  151.  * RETURN:      TRUE if Op and subtree was deleted
  152.  *
  153.  * DESCRIPTION: Perform any cleanup at the completion of an Op.
  154.  *
  155.  ******************************************************************************/
  156. static u8
  157. acpi_ps_complete_this_op (
  158. acpi_walk_state         *walk_state,
  159. acpi_parse_object       *op)
  160. {
  161. #ifndef PARSER_ONLY
  162. acpi_parse_object       *prev;
  163. acpi_parse_object       *next;
  164. const acpi_opcode_info  *parent_info;
  165. acpi_parse_object       *replacement_op = NULL;
  166. FUNCTION_TRACE_PTR ("Ps_complete_this_op", op);
  167. /* Delete this op and the subtree below it if asked to */
  168. if (((walk_state->parse_flags & ACPI_PARSE_TREE_MASK) == ACPI_PARSE_DELETE_TREE) &&
  169. (walk_state->op_info->class != AML_CLASS_ARGUMENT)) {
  170. /* Make sure that we only delete this subtree */
  171. if (op->parent) {
  172. /*
  173.  * Check if we need to replace the operator and its subtree
  174.  * with a return value op (placeholder op)
  175.  */
  176. parent_info = acpi_ps_get_opcode_info (op->parent->opcode);
  177. switch (parent_info->class) {
  178. case AML_CLASS_CONTROL:        /* IF, ELSE, WHILE only */
  179. break;
  180. case AML_CLASS_NAMED_OBJECT:   /* Scope, method, etc. */
  181. case AML_CLASS_CREATE:
  182. /*
  183.  * These opcodes contain Term_arg operands. The current
  184.  * op must be replace by a placeholder return op
  185.  */
  186. if ((op->parent->opcode == AML_REGION_OP)               ||
  187. (op->parent->opcode == AML_CREATE_FIELD_OP)         ||
  188. (op->parent->opcode == AML_CREATE_BIT_FIELD_OP)     ||
  189. (op->parent->opcode == AML_CREATE_BYTE_FIELD_OP)    ||
  190. (op->parent->opcode == AML_CREATE_WORD_FIELD_OP)    ||
  191. (op->parent->opcode == AML_CREATE_DWORD_FIELD_OP)   ||
  192. (op->parent->opcode == AML_CREATE_QWORD_FIELD_OP)) {
  193. replacement_op = acpi_ps_alloc_op (AML_INT_RETURN_VALUE_OP);
  194. if (!replacement_op) {
  195. return_VALUE (FALSE);
  196. }
  197. }
  198. break;
  199. default:
  200. replacement_op = acpi_ps_alloc_op (AML_INT_RETURN_VALUE_OP);
  201. if (!replacement_op) {
  202. return_VALUE (FALSE);
  203. }
  204. }
  205. /* We must unlink this op from the parent tree */
  206. prev = op->parent->value.arg;
  207. if (prev == op) {
  208. /* This op is the first in the list */
  209. if (replacement_op) {
  210. replacement_op->parent   = op->parent;
  211. replacement_op->value.arg = NULL;
  212. op->parent->value.arg    = replacement_op;
  213. replacement_op->next     = op->next;
  214. }
  215. else {
  216. op->parent->value.arg    = op->next;
  217. }
  218. }
  219. /* Search the parent list */
  220. else while (prev) {
  221. /* Traverse all siblings in the parent's argument list */
  222. next = prev->next;
  223. if (next == op) {
  224. if (replacement_op) {
  225. replacement_op->parent = op->parent;
  226. replacement_op->value.arg = NULL;
  227. prev->next = replacement_op;
  228. replacement_op->next = op->next;
  229. next = NULL;
  230. }
  231. else {
  232. prev->next = op->next;
  233. next = NULL;
  234. }
  235. }
  236. prev = next;
  237. }
  238. }
  239. /* Now we can actually delete the subtree rooted at op */
  240. acpi_ps_delete_parse_tree (op);
  241. return_VALUE (TRUE);
  242. }
  243. return_VALUE (FALSE);
  244. #else
  245. return (FALSE);
  246. #endif
  247. }
  248. /*******************************************************************************
  249.  *
  250.  * FUNCTION:    Acpi_ps_next_parse_state
  251.  *
  252.  * PARAMETERS:  Parser_state        - Current parser state object
  253.  *
  254.  * RETURN:
  255.  *
  256.  * DESCRIPTION:
  257.  *
  258.  ******************************************************************************/
  259. static acpi_status
  260. acpi_ps_next_parse_state (
  261. acpi_walk_state         *walk_state,
  262. acpi_parse_object       *op,
  263. acpi_status             callback_status)
  264. {
  265. acpi_parse_state        *parser_state = &walk_state->parser_state;
  266. acpi_status             status = AE_CTRL_PENDING;
  267. u8                      *start;
  268. u32                     package_length;
  269. FUNCTION_TRACE_PTR ("Ps_next_parse_state", op);
  270. switch (callback_status) {
  271. case AE_CTRL_TERMINATE:
  272. /*
  273.  * A control method was terminated via a RETURN statement.
  274.  * The walk of this method is complete.
  275.  */
  276. parser_state->aml = parser_state->aml_end;
  277. status = AE_CTRL_TERMINATE;
  278. break;
  279. case AE_CTRL_PENDING:
  280. /*
  281.  * Predicate of a WHILE was true and the loop just completed an
  282.  * execution.  Go back to the start of the loop and reevaluate the
  283.  * predicate.
  284.  */
  285. /* TBD: How to handle a break within a while. */
  286. /* This code attempts it */
  287. parser_state->aml = walk_state->aml_last_while;
  288. break;
  289. case AE_CTRL_TRUE:
  290. /*
  291.  * Predicate of an IF was true, and we are at the matching ELSE.
  292.  * Just close out this package
  293.  *
  294.  * Note: Parser_state->Aml is modified by the package length procedure
  295.  * TBD: [Investigate] perhaps it shouldn't, too much trouble
  296.  */
  297. start = parser_state->aml;
  298. package_length = acpi_ps_get_next_package_length (parser_state);
  299. parser_state->aml = start + package_length;
  300. break;
  301. case AE_CTRL_FALSE:
  302. /*
  303.  * Either an IF/WHILE Predicate was false or we encountered a BREAK
  304.  * opcode.  In both cases, we do not execute the rest of the
  305.  * package;  We simply close out the parent (finishing the walk of
  306.  * this branch of the tree) and continue execution at the parent
  307.  * level.
  308.  */
  309. parser_state->aml = parser_state->scope->parse_scope.pkg_end;
  310. /* In the case of a BREAK, just force a predicate (if any) to FALSE */
  311. walk_state->control_state->common.value = FALSE;
  312. status = AE_CTRL_END;
  313. break;
  314. case AE_CTRL_TRANSFER:
  315. /*
  316.  * A method call (invocation) -- transfer control
  317.  */
  318. status = AE_CTRL_TRANSFER;
  319. walk_state->prev_op = op;
  320. walk_state->method_call_op = op;
  321. walk_state->method_call_node = (op->value.arg)->node;
  322. /* Will return value (if any) be used by the caller? */
  323. walk_state->return_used = acpi_ds_is_result_used (op, walk_state);
  324. break;
  325. default:
  326. status = callback_status;
  327. if ((callback_status & AE_CODE_MASK) == AE_CODE_CONTROL) {
  328. status = AE_OK;
  329. }
  330. break;
  331. }
  332. return_ACPI_STATUS (status);
  333. }
  334. /*******************************************************************************
  335.  *
  336.  * FUNCTION:    Acpi_ps_parse_loop
  337.  *
  338.  * PARAMETERS:  Parser_state        - Current parser state object
  339.  *
  340.  * RETURN:      Status
  341.  *
  342.  * DESCRIPTION: Parse AML (pointed to by the current parser state) and return
  343.  *              a tree of ops.
  344.  *
  345.  ******************************************************************************/
  346. acpi_status
  347. acpi_ps_parse_loop (
  348. acpi_walk_state         *walk_state)
  349. {
  350. acpi_status             status = AE_OK;
  351. acpi_parse_object       *op = NULL;     /* current op */
  352. acpi_parse_object       *arg = NULL;
  353. acpi_parse_object       pre_op;
  354. acpi_parse_state        *parser_state;
  355. u8                      *aml_op_start;
  356. FUNCTION_TRACE_PTR ("Ps_parse_loop", walk_state);
  357. parser_state = &walk_state->parser_state;
  358. walk_state->arg_types = 0;
  359. #ifndef PARSER_ONLY
  360. if (walk_state->walk_type & WALK_METHOD_RESTART) {
  361. /* We are restarting a preempted control method */
  362. if (acpi_ps_has_completed_scope (parser_state)) {
  363. /*
  364.  * We must check if a predicate to an IF or WHILE statement
  365.  * was just completed
  366.  */
  367. if ((parser_state->scope->parse_scope.op) &&
  368.    ((parser_state->scope->parse_scope.op->opcode == AML_IF_OP) ||
  369. (parser_state->scope->parse_scope.op->opcode == AML_WHILE_OP)) &&
  370. (walk_state->control_state) &&
  371. (walk_state->control_state->common.state ==
  372. CONTROL_PREDICATE_EXECUTING)) {
  373. /*
  374.  * A predicate was just completed, get the value of the
  375.  * predicate and branch based on that value
  376.  */
  377. walk_state->op = NULL;
  378. status = acpi_ds_get_predicate_value (walk_state, TRUE);
  379. if (ACPI_FAILURE (status) &&
  380. ((status & AE_CODE_MASK) != AE_CODE_CONTROL)) {
  381. if (status == AE_AML_NO_RETURN_VALUE) {
  382. ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
  383. "Invoked method did not return a value, %sn",
  384. acpi_format_exception (status)));
  385. }
  386. ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Get_predicate Failed, %sn",
  387. acpi_format_exception (status)));
  388. return_ACPI_STATUS (status);
  389. }
  390. status = acpi_ps_next_parse_state (walk_state, op, status);
  391. }
  392. acpi_ps_pop_scope (parser_state, &op, &walk_state->arg_types, &walk_state->arg_count);
  393. ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Popped scope, Op=%pn", op));
  394. }
  395. else if (walk_state->prev_op) {
  396. /* We were in the middle of an op */
  397. op = walk_state->prev_op;
  398. walk_state->arg_types = walk_state->prev_arg_types;
  399. }
  400. }
  401. #endif
  402. /*
  403.  * Iterative parsing loop, while there is more aml to process:
  404.  */
  405. while ((parser_state->aml < parser_state->aml_end) || (op)) {
  406. if (!op) {
  407. /* Get the next opcode from the AML stream */
  408. aml_op_start = parser_state->aml;
  409. walk_state->aml_offset = parser_state->aml - parser_state->aml_start;
  410. walk_state->opcode    = acpi_ps_peek_opcode (parser_state);
  411. /*
  412.  * First cut to determine what we have found:
  413.  * 1) A valid AML opcode
  414.  * 2) A name string
  415.  * 3) An unknown/invalid opcode
  416.  */
  417. walk_state->op_info = acpi_ps_get_opcode_info (walk_state->opcode);
  418. switch (walk_state->op_info->class) {
  419. case AML_CLASS_ASCII:
  420. case AML_CLASS_PREFIX:
  421. /*
  422.  * Starts with a valid prefix or ASCII char, this is a name
  423.  * string.  Convert the bare name string to a namepath.
  424.  */
  425. walk_state->opcode = AML_INT_NAMEPATH_OP;
  426. walk_state->arg_types = ARGP_NAMESTRING;
  427. break;
  428. case AML_CLASS_UNKNOWN:
  429. /* The opcode is unrecognized.  Just skip unknown opcodes */
  430. ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
  431. "Found unknown opcode %X at AML offset %X, ignoringn",
  432. walk_state->opcode, walk_state->aml_offset));
  433. DUMP_BUFFER (parser_state->aml, 128);
  434. /* Assume one-byte bad opcode */
  435. parser_state->aml++;
  436. continue;
  437. default:
  438. /* Found opcode info, this is a normal opcode */
  439. parser_state->aml += acpi_ps_get_opcode_size (walk_state->opcode);
  440. walk_state->arg_types = walk_state->op_info->parse_args;
  441. break;
  442. }
  443. /* Create Op structure and append to parent's argument list */
  444. if (walk_state->op_info->flags & AML_NAMED) {
  445. pre_op.value.arg = NULL;
  446. pre_op.opcode = walk_state->opcode;
  447. while (GET_CURRENT_ARG_TYPE (walk_state->arg_types) != ARGP_NAME) {
  448. arg = acpi_ps_get_next_arg (parser_state,
  449.  GET_CURRENT_ARG_TYPE (walk_state->arg_types),
  450.  &walk_state->arg_count);
  451. acpi_ps_append_arg (&pre_op, arg);
  452. INCREMENT_ARG_LIST (walk_state->arg_types);
  453. }
  454. /* We know that this arg is a name, move to next arg */
  455. INCREMENT_ARG_LIST (walk_state->arg_types);
  456. if (walk_state->descending_callback != NULL) {
  457. /*
  458.  * Find the object.  This will either insert the object into
  459.  * the namespace or simply look it up
  460.  */
  461. walk_state->op = NULL;
  462. status = walk_state->descending_callback (walk_state, &op);
  463. /* TBD: check status here? */
  464. if (ACPI_FAILURE (status)) {
  465. ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "During name lookup/catalog, %sn",
  466. acpi_format_exception (status)));
  467. goto close_this_op;
  468. }
  469. if (op == NULL) {
  470. continue;
  471. }
  472. status = acpi_ps_next_parse_state (walk_state, op, status);
  473. if (status == AE_CTRL_PENDING) {
  474. status = AE_OK;
  475. goto close_this_op;
  476. }
  477. if (ACPI_FAILURE (status)) {
  478. goto close_this_op;
  479. }
  480. }
  481. acpi_ps_append_arg (op, pre_op.value.arg);
  482. acpi_gbl_depth++;
  483. if (op->opcode == AML_REGION_OP) {
  484. /*
  485.  * Defer final parsing of an Operation_region body,
  486.  * because we don't have enough info in the first pass
  487.  * to parse it correctly (i.e., there may be method
  488.  * calls within the Term_arg elements of the body.
  489.  *
  490.  * However, we must continue parsing because
  491.  * the opregion is not a standalone package --
  492.  * we don't know where the end is at this point.
  493.  *
  494.  * (Length is unknown until parse of the body complete)
  495.  */
  496. ((acpi_parse2_object * ) op)->data    = aml_op_start;
  497. ((acpi_parse2_object * ) op)->length  = 0;
  498. }
  499. }
  500. else {
  501. /* Not a named opcode, just allocate Op and append to parent */
  502. walk_state->op_info = acpi_ps_get_opcode_info (walk_state->opcode);
  503. op = acpi_ps_alloc_op (walk_state->opcode);
  504. if (!op) {
  505. return_ACPI_STATUS (AE_NO_MEMORY);
  506. }
  507. if (walk_state->op_info->flags & AML_CREATE) {
  508. /*
  509.  * Backup to beginning of Create_xXXfield declaration
  510.  * Body_length is unknown until we parse the body
  511.  */
  512. ((acpi_parse2_object * ) op)->data    = aml_op_start;
  513. ((acpi_parse2_object * ) op)->length  = 0;
  514. }
  515. acpi_ps_append_arg (acpi_ps_get_parent_scope (parser_state), op);
  516. if ((walk_state->descending_callback != NULL)) {
  517. /*
  518.  * Find the object.  This will either insert the object into
  519.  * the namespace or simply look it up
  520.  */
  521. walk_state->op    = op;
  522. status = walk_state->descending_callback (walk_state, &op);
  523. status = acpi_ps_next_parse_state (walk_state, op, status);
  524. if (status == AE_CTRL_PENDING) {
  525. status = AE_OK;
  526. goto close_this_op;
  527. }
  528. if (ACPI_FAILURE (status)) {
  529. goto close_this_op;
  530. }
  531. }
  532. }
  533. op->aml_offset = walk_state->aml_offset;
  534. if (walk_state->op_info) {
  535. ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
  536. "Op=%p Opcode=%4.4X Aml %p Oft=%5.5Xn",
  537.  op, op->opcode, parser_state->aml, op->aml_offset));
  538. }
  539. }
  540. /* Start Arg_count at zero because we don't know if there are any args yet */
  541. walk_state->arg_count = 0;
  542. if (walk_state->arg_types) /* Are there any arguments that must be processed? */ {
  543. /* get arguments */
  544. switch (op->opcode) {
  545. case AML_BYTE_OP:       /* AML_BYTEDATA_ARG */
  546. case AML_WORD_OP:       /* AML_WORDDATA_ARG */
  547. case AML_DWORD_OP:      /* AML_DWORDATA_ARG */
  548. case AML_QWORD_OP:      /* AML_QWORDATA_ARG */
  549. case AML_STRING_OP:     /* AML_ASCIICHARLIST_ARG */
  550. /* fill in constant or string argument directly */
  551. acpi_ps_get_next_simple_arg (parser_state,
  552.  GET_CURRENT_ARG_TYPE (walk_state->arg_types), op);
  553. break;
  554. case AML_INT_NAMEPATH_OP:   /* AML_NAMESTRING_ARG */
  555. acpi_ps_get_next_namepath (parser_state, op, &walk_state->arg_count, 1);
  556. walk_state->arg_types = 0;
  557. break;
  558. default:
  559. /* Op is not a constant or string, append each argument */
  560. while (GET_CURRENT_ARG_TYPE (walk_state->arg_types) && !walk_state->arg_count) {
  561. walk_state->aml_offset = parser_state->aml - parser_state->aml_start;
  562. arg = acpi_ps_get_next_arg (parser_state,
  563.  GET_CURRENT_ARG_TYPE (walk_state->arg_types),
  564.  &walk_state->arg_count);
  565. if (arg) {
  566. arg->aml_offset = walk_state->aml_offset;
  567. acpi_ps_append_arg (op, arg);
  568. }
  569. INCREMENT_ARG_LIST (walk_state->arg_types);
  570. }
  571. /* For a method, save the length and address of the body */
  572. if (op->opcode == AML_METHOD_OP) {
  573. /*
  574.  * Skip parsing of control method or opregion body,
  575.  * because we don't have enough info in the first pass
  576.  * to parse them correctly.
  577.  */
  578. ((acpi_parse2_object * ) op)->data    = parser_state->aml;
  579. ((acpi_parse2_object * ) op)->length  = (u32) (parser_state->pkg_end -
  580.    parser_state->aml);
  581. /*
  582.  * Skip body of method.  For Op_regions, we must continue
  583.  * parsing because the opregion is not a standalone
  584.  * package (We don't know where the end is).
  585.  */
  586. parser_state->aml   = parser_state->pkg_end;
  587. walk_state->arg_count          = 0;
  588. }
  589. break;
  590. }
  591. }
  592. /*
  593.  * Zero Arg_count means that all arguments for this op have been processed
  594.  */
  595. if (!walk_state->arg_count) {
  596. /* completed Op, prepare for next */
  597. walk_state->op_info = acpi_ps_get_opcode_info (op->opcode);
  598. if (walk_state->op_info->flags & AML_NAMED) {
  599. if (acpi_gbl_depth) {
  600. acpi_gbl_depth--;
  601. }
  602. if (op->opcode == AML_REGION_OP) {
  603. /*
  604.  * Skip parsing of control method or opregion body,
  605.  * because we don't have enough info in the first pass
  606.  * to parse them correctly.
  607.  *
  608.  * Completed parsing an Op_region declaration, we now
  609.  * know the length.
  610.  */
  611. ((acpi_parse2_object * ) op)->length = (u32) (parser_state->aml -
  612.    ((acpi_parse2_object * ) op)->data);
  613. }
  614. }
  615. if (walk_state->op_info->flags & AML_CREATE) {
  616. /*
  617.  * Backup to beginning of Create_xXXfield declaration (1 for
  618.  * Opcode)
  619.  *
  620.  * Body_length is unknown until we parse the body
  621.  */
  622. ((acpi_parse2_object * ) op)->length = (u32) (parser_state->aml -
  623.    ((acpi_parse2_object * ) op)->data);
  624. }
  625. /* This op complete, notify the dispatcher */
  626. if (walk_state->ascending_callback != NULL) {
  627. walk_state->op    = op;
  628. walk_state->opcode = op->opcode;
  629. status = walk_state->ascending_callback (walk_state);
  630. status = acpi_ps_next_parse_state (walk_state, op, status);
  631. if (status == AE_CTRL_PENDING) {
  632. status = AE_OK;
  633. goto close_this_op;
  634. }
  635. }
  636. close_this_op:
  637. /*
  638.  * Finished one argument of the containing scope
  639.  */
  640. parser_state->scope->parse_scope.arg_count--;
  641. /* Close this Op (may result in parse subtree deletion) */
  642. if (acpi_ps_complete_this_op (walk_state, op)) {
  643. op = NULL;
  644. }
  645. switch (status) {
  646. case AE_OK:
  647. break;
  648. case AE_CTRL_TRANSFER:
  649. /*
  650.  * We are about to transfer to a called method.
  651.  */
  652. walk_state->prev_op = op;
  653. walk_state->prev_arg_types = walk_state->arg_types;
  654. return_ACPI_STATUS (status);
  655. break;
  656. case AE_CTRL_END:
  657. acpi_ps_pop_scope (parser_state, &op, &walk_state->arg_types, &walk_state->arg_count);
  658. walk_state->op    = op;
  659. walk_state->op_info = acpi_ps_get_opcode_info (op->opcode);
  660. walk_state->opcode = op->opcode;
  661. status = walk_state->ascending_callback (walk_state);
  662. status = acpi_ps_next_parse_state (walk_state, op, status);
  663. acpi_ps_complete_this_op (walk_state, op);
  664. op = NULL;
  665. status = AE_OK;
  666. break;
  667. case AE_CTRL_TERMINATE:
  668. status = AE_OK;
  669. /* Clean up */
  670. do {
  671. if (op) {
  672. acpi_ps_complete_this_op (walk_state, op);
  673. }
  674. acpi_ps_pop_scope (parser_state, &op, &walk_state->arg_types, &walk_state->arg_count);
  675. } while (op);
  676. return_ACPI_STATUS (status);
  677. break;
  678. default:  /* All other non-AE_OK status */
  679. if (op == NULL) {
  680. acpi_ps_pop_scope (parser_state, &op, &walk_state->arg_types, &walk_state->arg_count);
  681. }
  682. walk_state->prev_op = op;
  683. walk_state->prev_arg_types = walk_state->arg_types;
  684. /*
  685.  * TEMP:
  686.  */
  687. return_ACPI_STATUS (status);
  688. break;
  689. }
  690. /* This scope complete? */
  691. if (acpi_ps_has_completed_scope (parser_state)) {
  692. acpi_ps_pop_scope (parser_state, &op, &walk_state->arg_types, &walk_state->arg_count);
  693. ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Popped scope, Op=%pn", op));
  694. }
  695. else {
  696. op = NULL;
  697. }
  698. }
  699. /* Arg_count is non-zero */
  700. else {
  701. /* complex argument, push Op and prepare for argument */
  702. acpi_ps_push_scope (parser_state, op, walk_state->arg_types, walk_state->arg_count);
  703. op = NULL;
  704. }
  705. } /* while Parser_state->Aml */
  706. /*
  707.  * Complete the last Op (if not completed), and clear the scope stack.
  708.  * It is easily possible to end an AML "package" with an unbounded number
  709.  * of open scopes (such as when several ASL blocks are closed with
  710.  * sequential closing braces).  We want to terminate each one cleanly.
  711.  */
  712. ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "AML package complete at Op %pn", op));
  713. do {
  714. if (op) {
  715. if (walk_state->ascending_callback != NULL) {
  716. walk_state->op    = op;
  717. walk_state->op_info = acpi_ps_get_opcode_info (op->opcode);
  718. walk_state->opcode = op->opcode;
  719. status = walk_state->ascending_callback (walk_state);
  720. status = acpi_ps_next_parse_state (walk_state, op, status);
  721. if (status == AE_CTRL_PENDING) {
  722. status = AE_OK;
  723. goto close_this_op;
  724. }
  725. if (status == AE_CTRL_TERMINATE) {
  726. status = AE_OK;
  727. /* Clean up */
  728. do {
  729. if (op) {
  730. acpi_ps_complete_this_op (walk_state, op);
  731. }
  732. acpi_ps_pop_scope (parser_state, &op, &walk_state->arg_types, &walk_state->arg_count);
  733. } while (op);
  734. return_ACPI_STATUS (status);
  735. }
  736. else if (ACPI_FAILURE (status)) {
  737. acpi_ps_complete_this_op (walk_state, op);
  738. return_ACPI_STATUS (status);
  739. }
  740. }
  741. acpi_ps_complete_this_op (walk_state, op);
  742. }
  743. acpi_ps_pop_scope (parser_state, &op, &walk_state->arg_types, &walk_state->arg_count);
  744. } while (op);
  745. return_ACPI_STATUS (status);
  746. }
  747. /*******************************************************************************
  748.  *
  749.  * FUNCTION:    Acpi_ps_parse_aml
  750.  *
  751.  * PARAMETERS:  Start_scope     - The starting point of the parse.  Becomes the
  752.  *                                root of the parsed op tree.
  753.  *              Aml             - Pointer to the raw AML code to parse
  754.  *              Aml_size        - Length of the AML to parse
  755.  *
  756.  *
  757.  * RETURN:      Status
  758.  *
  759.  * DESCRIPTION: Parse raw AML and return a tree of ops
  760.  *
  761.  ******************************************************************************/
  762. acpi_status
  763. acpi_ps_parse_aml (
  764. acpi_walk_state         *walk_state)
  765. {
  766. acpi_status             status;
  767. acpi_walk_list          walk_list;
  768. acpi_walk_list          *prev_walk_list = acpi_gbl_current_walk_list;
  769. acpi_walk_state         *previous_walk_state;
  770. FUNCTION_TRACE ("Ps_parse_aml");
  771. ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Entered with Walk_state=%p Aml=%p size=%Xn",
  772. walk_state, walk_state->parser_state.aml, walk_state->parser_state.aml_size));
  773. /* Create and initialize a new walk list */
  774. walk_list.walk_state            = NULL;
  775. walk_list.acquired_mutex_list.prev = NULL;
  776. walk_list.acquired_mutex_list.next = NULL;
  777. walk_state->walk_list = &walk_list;
  778. acpi_ds_push_walk_state (walk_state, &walk_list);
  779. /* TBD: [Restructure] TEMP until we pass Walk_state to the interpreter
  780.  */
  781. acpi_gbl_current_walk_list = &walk_list;
  782. /*
  783.  * Execute the walk loop as long as there is a valid Walk State.  This
  784.  * handles nested control method invocations without recursion.
  785.  */
  786. ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "State=%pn", walk_state));
  787. status = AE_OK;
  788. while (walk_state) {
  789. if (ACPI_SUCCESS (status)) {
  790. /*
  791.  * The Parse_loop executes AML until the method terminates
  792.  * or calls another method.
  793.  */
  794. status = acpi_ps_parse_loop (walk_state);
  795. }
  796. ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
  797. "Completed one call to walk loop, State=%pn", walk_state));
  798. if (status == AE_CTRL_TRANSFER) {
  799. /*
  800.  * A method call was detected.
  801.  * Transfer control to the called control method
  802.  */
  803. status = acpi_ds_call_control_method (&walk_list, walk_state, NULL);
  804. /*
  805.  * If the transfer to the new method method call worked, a new walk
  806.  * state was created -- get it
  807.  */
  808. walk_state = acpi_ds_get_current_walk_state (&walk_list);
  809. continue;
  810. }
  811. else if (status == AE_CTRL_TERMINATE) {
  812. status = AE_OK;
  813. }
  814. /* We are done with this walk, move on to the parent if any */
  815. walk_state = acpi_ds_pop_walk_state (&walk_list);
  816. /* Reset the current scope to the beginning of scope stack */
  817. acpi_ds_scope_stack_clear (walk_state);
  818. /*
  819.  * If we just returned from the execution of a control method,
  820.  * there's lots of cleanup to do
  821.  */
  822. if ((walk_state->parse_flags & ACPI_PARSE_MODE_MASK) == ACPI_PARSE_EXECUTE) {
  823. acpi_ds_terminate_control_method (walk_state);
  824. }
  825. /* Delete this walk state and all linked control states */
  826. acpi_ps_cleanup_scope (&walk_state->parser_state);
  827. previous_walk_state = walk_state;
  828. ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Return_value=%p, State=%pn",
  829. walk_state->return_desc, walk_state));
  830. /* Check if we have restarted a preempted walk */
  831. walk_state = acpi_ds_get_current_walk_state (&walk_list);
  832. if (walk_state) {
  833. if (ACPI_SUCCESS (status)) {
  834. /* There is another walk state, restart it */
  835. /*
  836.  * If the method returned value is not used by the parent,
  837.  * The object is deleted
  838.  */
  839. acpi_ds_restart_control_method (walk_state, previous_walk_state->return_desc);
  840. walk_state->walk_type |= WALK_METHOD_RESTART;
  841. }
  842. }
  843. /*
  844.  * Just completed a 1st-level method, save the final internal return
  845.  * value (if any)
  846.  */
  847. else if (previous_walk_state->caller_return_desc) {
  848. *(previous_walk_state->caller_return_desc) = previous_walk_state->return_desc; /* NULL if no return value */
  849. }
  850. else if (previous_walk_state->return_desc) {
  851. /* Caller doesn't want it, must delete it */
  852. acpi_ut_remove_reference (previous_walk_state->return_desc);
  853. }
  854. acpi_ds_delete_walk_state (previous_walk_state);
  855. }
  856. /* Normal exit */
  857. acpi_ex_release_all_mutexes ((acpi_operand_object *) &walk_list.acquired_mutex_list);
  858. acpi_gbl_current_walk_list = prev_walk_list;
  859. return_ACPI_STATUS (status);
  860. }