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