:pserver:cvsanon@mok.lvcm.com:/CVS/ReactOS reactos
[reactos.git] / drivers / bus / acpi / parser / psparse.c
1 /******************************************************************************
2  *
3  * Module Name: psparse - Parser top level AML parse routines
4  *              $Revision$
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_peek_opcode
55  *
56  * PARAMETERS:  None
57  *
58  * RETURN:      Status
59  *
60  * DESCRIPTION: Get next AML opcode (without incrementing AML pointer)
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 (Acpi_aml) == AML_LEQUAL
116          *               || GET8 (Acpi_aml) == AML_LGREATER
117          *               || GET8 (Acpi_aml) == AML_LLESS)))
118          *
119          *     extended Opcode, !=, <=, or >=
120          */
121
122         if (opcode == AML_EXTOP) {
123                 /* Extended opcode */
124
125                 opcode = (u16) ((opcode << 8) | GET8 (aml));
126                 aml++;
127         }
128
129         /* don't convert bare name to a namepath */
130
131         return (opcode);
132 }
133
134
135 /*******************************************************************************
136  *
137  * FUNCTION:    Acpi_ps_create_state
138  *
139  * PARAMETERS:  Acpi_aml            - Acpi_aml code pointer
140  *              Acpi_aml_size       - Length of AML code
141  *
142  * RETURN:      A new parser state object
143  *
144  * DESCRIPTION: Create and initialize a new parser state object
145  *
146  ******************************************************************************/
147
148 ACPI_PARSE_STATE *
149 acpi_ps_create_state (
150         u8                      *aml,
151         u32                     aml_size)
152 {
153         ACPI_PARSE_STATE        *parser_state;
154
155
156         parser_state = acpi_cm_callocate (sizeof (ACPI_PARSE_STATE));
157         if (!parser_state) {
158                 return (NULL);
159         }
160
161         parser_state->aml      = aml;
162         parser_state->aml_end  = aml + aml_size;
163         parser_state->pkg_end  = parser_state->aml_end;
164         parser_state->aml_start = aml;
165
166
167         return (parser_state);
168 }
169
170
171 /*******************************************************************************
172  *
173  * FUNCTION:    Acpi_ps_find_object
174  *
175  * PARAMETERS:  Opcode          - Current opcode
176  *              Parser_state    - Current state
177  *              Walk_state      - Current state
178  *              *Op             - Where found/new op is returned
179  *
180  * RETURN:      Status
181  *
182  * DESCRIPTION: Find a named object.  Two versions - one to search the parse
183  *              tree (for parser-only applications such as acpidump), another
184  *              to search the ACPI internal namespace (the parse tree may no
185  *              longer exist)
186  *
187  ******************************************************************************/
188
189 #ifdef PARSER_ONLY
190
191 ACPI_STATUS
192 acpi_ps_find_object (
193         u16                     opcode,
194         ACPI_PARSE_OBJECT       *op,
195         ACPI_WALK_STATE         *walk_state,
196         ACPI_PARSE_OBJECT       **out_op)
197 {
198         NATIVE_CHAR             *path;
199
200
201         /* We are only interested in opcodes that have an associated name */
202
203         if (!acpi_ps_is_named_op (opcode)) {
204                 *out_op = op;
205                 return (AE_OK);
206         }
207
208         /* Find the name in the parse tree */
209
210         path = acpi_ps_get_next_namestring (walk_state->parser_state);
211
212         *out_op = acpi_ps_find (acpi_ps_get_parent_scope (walk_state->parser_state),
213                           path, opcode, 1);
214
215         if (!(*out_op)) {
216                 return (AE_NOT_FOUND);
217         }
218
219         return (AE_OK);
220 }
221
222 #endif
223
224
225 /*******************************************************************************
226  *
227  * FUNCTION:    Acpi_ps_complete_this_op
228  *
229  * PARAMETERS:  Walk_state      - Current State
230  *              Op              - Op to complete
231  *
232  * RETURN:      TRUE if Op and subtree was deleted
233  *
234  * DESCRIPTION: Perform any cleanup at the completion of an Op.
235  *
236  ******************************************************************************/
237
238 static u8
239 acpi_ps_complete_this_op (
240         ACPI_WALK_STATE         *walk_state,
241         ACPI_PARSE_OBJECT       *op)
242 {
243 #ifndef PARSER_ONLY
244         ACPI_PARSE_OBJECT       *prev;
245         ACPI_PARSE_OBJECT       *next;
246         ACPI_OPCODE_INFO        *op_info;
247         ACPI_OPCODE_INFO        *parent_info;
248         u32                     opcode_class;
249         ACPI_PARSE_OBJECT       *replacement_op = NULL;
250
251
252         op_info     = acpi_ps_get_opcode_info (op->opcode);
253         opcode_class = ACPI_GET_OP_CLASS (op_info);
254
255
256         /* Delete this op and the subtree below it if asked to */
257
258         if (((walk_state->parse_flags & ACPI_PARSE_TREE_MASK) == ACPI_PARSE_DELETE_TREE) &&
259                 (opcode_class != OPTYPE_CONSTANT)       &&
260                 (opcode_class != OPTYPE_LITERAL)        &&
261                 (opcode_class != OPTYPE_LOCAL_VARIABLE) &&
262                 (opcode_class != OPTYPE_METHOD_ARGUMENT) &&
263                 (opcode_class != OPTYPE_DATA_TERM)      &&
264                 (op->opcode  != AML_NAMEPATH_OP)) {
265                 /* Make sure that we only delete this subtree */
266
267                 if (op->parent) {
268                         /*
269                          * Check if we need to replace the operator and its subtree
270                          * with a return value op (placeholder op)
271                          */
272
273                         parent_info = acpi_ps_get_opcode_info (op->parent->opcode);
274
275                         switch (ACPI_GET_OP_CLASS (parent_info)) {
276                         case OPTYPE_CONTROL:        /* IF, ELSE, WHILE only */
277                                 break;
278
279                         case OPTYPE_NAMED_OBJECT:   /* Scope, method, etc. */
280
281                                 /*
282                                  * These opcodes contain Term_arg operands. The current
283                                  * op must be replace by a placeholder return op
284                                  */
285
286                                 if ((op->parent->opcode == AML_REGION_OP)       ||
287                                         (op->parent->opcode == AML_CREATE_FIELD_OP) ||
288                                         (op->parent->opcode == AML_BIT_FIELD_OP)    ||
289                                         (op->parent->opcode == AML_BYTE_FIELD_OP)   ||
290                                         (op->parent->opcode == AML_WORD_FIELD_OP)   ||
291                                         (op->parent->opcode == AML_DWORD_FIELD_OP)  ||
292                                         (op->parent->opcode == AML_QWORD_FIELD_OP)) {
293                                         replacement_op = acpi_ps_alloc_op (AML_RETURN_VALUE_OP);
294                                         if (!replacement_op) {
295                                                 return (FALSE);
296                                         }
297                                 }
298
299                                 break;
300
301                         default:
302                                 replacement_op = acpi_ps_alloc_op (AML_RETURN_VALUE_OP);
303                                 if (!replacement_op) {
304                                         return (FALSE);
305                                 }
306                         }
307
308                         /* We must unlink this op from the parent tree */
309
310                         prev = op->parent->value.arg;
311                         if (prev == op) {
312                                 /* This op is the first in the list */
313
314                                 if (replacement_op) {
315                                         replacement_op->parent   = op->parent;
316                                         replacement_op->value.arg = NULL;
317                                         op->parent->value.arg    = replacement_op;
318                                         replacement_op->next     = op->next;
319                                 }
320                                 else {
321                                         op->parent->value.arg    = op->next;
322                                 }
323                         }
324
325                         /* Search the parent list */
326
327                         else while (prev) {
328                                 /* Traverse all siblings in the parent's argument list */
329
330                                 next = prev->next;
331                                 if (next == op) {
332                                         if (replacement_op) {
333                                                 replacement_op->parent = op->parent;
334                                                 replacement_op->value.arg = NULL;
335                                                 prev->next = replacement_op;
336                                                 replacement_op->next = op->next;
337                                                 next = NULL;
338                                         }
339                                         else {
340                                                 prev->next = op->next;
341                                                 next = NULL;
342                                         }
343                                 }
344
345                                 prev = next;
346                         }
347
348                 }
349
350                 /* Now we can actually delete the subtree rooted at op */
351
352                 acpi_ps_delete_parse_tree (op);
353
354                 return (TRUE);
355         }
356
357         return (FALSE);
358
359 #else
360         return (FALSE);
361 #endif
362 }
363
364
365 /*******************************************************************************
366  *
367  * FUNCTION:    Acpi_ps_next_parse_state
368  *
369  * PARAMETERS:  Parser_state        - Current parser state object
370  *
371  * RETURN:
372  *
373  * DESCRIPTION:
374  *
375  ******************************************************************************/
376
377 static ACPI_STATUS
378 acpi_ps_next_parse_state (
379         ACPI_WALK_STATE         *walk_state,
380         ACPI_PARSE_OBJECT       *op,
381         ACPI_STATUS             callback_status)
382 {
383         ACPI_PARSE_STATE        *parser_state = walk_state->parser_state;
384         ACPI_STATUS             status = AE_CTRL_PENDING;
385         u8                      *start;
386         u32                     package_length;
387
388
389         switch (callback_status) {
390         case AE_CTRL_TERMINATE:
391
392                 /*
393                  * A control method was terminated via a RETURN statement.
394                  * The walk of this method is complete.
395                  */
396
397                 parser_state->aml = parser_state->aml_end;
398                 status = AE_CTRL_TERMINATE;
399                 break;
400
401
402         case AE_CTRL_PENDING:
403
404                         /*
405                          * Predicate of a WHILE was true and the loop just completed an
406                          * execution.  Go back to the start of the loop and reevaluate the
407                          * predicate.
408                          */
409 /*            Walk_state->Control_state->Common.State =
410                                         CONTROL_PREDICATE_EXECUTING;*/
411
412                 /* TBD: How to handle a break within a while. */
413                 /* This code attempts it */
414
415                 parser_state->aml = walk_state->aml_last_while;
416                 break;
417
418
419         case AE_CTRL_TRUE:
420                         /*
421                          * Predicate of an IF was true, and we are at the matching ELSE.
422                          * Just close out this package
423                          *
424                          * Note: Parser_state->Aml is modified by the package length procedure
425                          * TBD: [Investigate] perhaps it shouldn't, too much trouble
426                          */
427                 start = parser_state->aml;
428                 package_length = acpi_ps_get_next_package_length (parser_state);
429                 parser_state->aml = start + package_length;
430                 break;
431
432
433         case AE_CTRL_FALSE:
434
435                 /*
436                  * Either an IF/WHILE Predicate was false or we encountered a BREAK
437                  * opcode.  In both cases, we do not execute the rest of the
438                  * package;  We simply close out the parent (finishing the walk of
439                  * this branch of the tree) and continue execution at the parent
440                  * level.
441                  */
442
443                 parser_state->aml = parser_state->scope->parse_scope.pkg_end;
444
445                 /* In the case of a BREAK, just force a predicate (if any) to FALSE */
446
447                 walk_state->control_state->common.value = FALSE;
448                 status = AE_CTRL_END;
449                 break;
450
451
452         case AE_CTRL_TRANSFER:
453
454                 /*
455                  * A method call (invocation) -- transfer control
456                  */
457                 status = AE_CTRL_TRANSFER;
458                 walk_state->prev_op = op;
459                 walk_state->method_call_op = op;
460                 walk_state->method_call_node = (op->value.arg)->node;
461
462                 /* Will return value (if any) be used by the caller? */
463
464                 walk_state->return_used = acpi_ds_is_result_used (op, walk_state);
465                 break;
466
467
468         default:
469                 status = callback_status;
470                 if ((callback_status & AE_CODE_MASK) == AE_CODE_CONTROL) {
471                         status = AE_OK;
472                 }
473                 break;
474         }
475
476
477         return (status);
478 }
479
480
481 /*******************************************************************************
482  *
483  * FUNCTION:    Acpi_ps_parse_loop
484  *
485  * PARAMETERS:  Parser_state        - Current parser state object
486  *
487  * RETURN:      Status
488  *
489  * DESCRIPTION: Parse AML (pointed to by the current parser state) and return
490  *              a tree of ops.
491  *
492  ******************************************************************************/
493
494 ACPI_STATUS
495 acpi_ps_parse_loop (
496         ACPI_WALK_STATE         *walk_state)
497 {
498         ACPI_STATUS             status = AE_OK;
499         ACPI_PARSE_OBJECT       *op = NULL;     /* current op */
500         ACPI_OPCODE_INFO        *op_info;
501         ACPI_PARSE_OBJECT       *arg = NULL;
502         ACPI_PARSE2_OBJECT      *deferred_op;
503         u32                     arg_count;      /* push for fixed or var args */
504         u32                     arg_types = 0;
505         ACPI_PTRDIFF            aml_offset;
506         u16                     opcode;
507         ACPI_PARSE_OBJECT       pre_op;
508         ACPI_PARSE_STATE        *parser_state;
509         u8                      *aml_op_start;
510
511
512         parser_state = walk_state->parser_state;
513
514 #ifndef PARSER_ONLY
515         if (walk_state->walk_type & WALK_METHOD_RESTART) {
516                 /* We are restarting a preempted control method */
517
518                 if (acpi_ps_has_completed_scope (parser_state)) {
519                         /*
520                          * We must check if a predicate to an IF or WHILE statement
521                          * was just completed
522                          */
523                         if ((parser_state->scope->parse_scope.op) &&
524                                 ((parser_state->scope->parse_scope.op->opcode == AML_IF_OP) ||
525                                 (parser_state->scope->parse_scope.op->opcode == AML_WHILE_OP)) &&
526                                 (walk_state->control_state) &&
527                                 (walk_state->control_state->common.state ==
528                                         CONTROL_PREDICATE_EXECUTING)) {
529
530                                 /*
531                                  * A predicate was just completed, get the value of the
532                                  * predicate and branch based on that value
533                                  */
534
535                                 status = acpi_ds_get_predicate_value (walk_state, NULL, TRUE);
536                                 if (ACPI_FAILURE (status) &&
537                                         ((status & AE_CODE_MASK) != AE_CODE_CONTROL)) {
538                                         return (status);
539                                 }
540
541                                 status = acpi_ps_next_parse_state (walk_state, op, status);
542                         }
543
544                         acpi_ps_pop_scope (parser_state, &op, &arg_types, &arg_count);
545                 }
546
547                 else if (walk_state->prev_op) {
548                         /* We were in the middle of an op */
549
550                         op = walk_state->prev_op;
551                         arg_types = walk_state->prev_arg_types;
552                 }
553         }
554 #endif
555
556         /*
557          * Iterative parsing loop, while there is more aml to process:
558          */
559         while ((parser_state->aml < parser_state->aml_end) || (op)) {
560                 if (!op) {
561                         /* Get the next opcode from the AML stream */
562
563                         aml_op_start = parser_state->aml;
564                         aml_offset = parser_state->aml - parser_state->aml_start;
565                         opcode     = acpi_ps_peek_opcode (parser_state);
566
567                         /*
568                          * First cut to determine what we have found:
569                          * 1) A valid AML opcode
570                          * 2) A name string
571                          * 3) An unknown/invalid opcode
572                          */
573
574                         op_info = acpi_ps_get_opcode_info (opcode);
575                         switch (ACPI_GET_OP_TYPE (op_info)) {
576                         case ACPI_OP_TYPE_OPCODE:
577
578                                 /* Found opcode info, this is a normal opcode */
579
580                                 parser_state->aml += acpi_ps_get_opcode_size (opcode);
581                                 arg_types = op_info->parse_args;
582                                 break;
583
584                         case ACPI_OP_TYPE_ASCII:
585                         case ACPI_OP_TYPE_PREFIX:
586                                 /*
587                                  * Starts with a valid prefix or ASCII char, this is a name
588                                  * string.  Convert the bare name string to a namepath.
589                                  */
590
591                                 opcode = AML_NAMEPATH_OP;
592                                 arg_types = ARGP_NAMESTRING;
593                                 break;
594
595                         case ACPI_OP_TYPE_UNKNOWN:
596
597                                 /* The opcode is unrecognized.  Just skip unknown opcodes */
598
599                                 /* Assume one-byte bad opcode */
600
601                                 parser_state->aml++;
602                                 continue;
603                         }
604
605
606                         /* Create Op structure and append to parent's argument list */
607
608                         if (acpi_ps_is_named_op (opcode)) {
609                                 pre_op.value.arg = NULL;
610                                 pre_op.opcode = opcode;
611
612                                 while (GET_CURRENT_ARG_TYPE (arg_types) != ARGP_NAME) {
613                                         arg = acpi_ps_get_next_arg (parser_state,
614                                                          GET_CURRENT_ARG_TYPE (arg_types),
615                                                          &arg_count);
616                                         acpi_ps_append_arg (&pre_op, arg);
617                                         INCREMENT_ARG_LIST (arg_types);
618                                 }
619
620
621                                 /* We know that this arg is a name, move to next arg */
622
623                                 INCREMENT_ARG_LIST (arg_types);
624
625                                 if (walk_state->descending_callback != NULL) {
626                                         /*
627                                          * Find the object.  This will either insert the object into
628                                          * the namespace or simply look it up
629                                          */
630                                         status = walk_state->descending_callback (opcode, NULL, walk_state, &op);
631                                         if (op == NULL) {
632                                                 continue;
633                                         }
634                                         status = acpi_ps_next_parse_state (walk_state, op, status);
635                                         if (status == AE_CTRL_PENDING) {
636                                                 status = AE_OK;
637                                                 goto close_this_op;
638                                         }
639
640                                         if (ACPI_FAILURE (status)) {
641                                                 goto close_this_op;
642                                         }
643                                 }
644
645                                 acpi_ps_append_arg (op, pre_op.value.arg);
646                                 acpi_gbl_depth++;
647
648
649                                 if (op->opcode == AML_REGION_OP) {
650                                         deferred_op = acpi_ps_to_extended_op (op);
651                                         if (deferred_op) {
652                                                 /*
653                                                  * Defer final parsing of an Operation_region body,
654                                                  * because we don't have enough info in the first pass
655                                                  * to parse it correctly (i.e., there may be method
656                                                  * calls within the Term_arg elements of the body.
657                                                  *
658                                                  * However, we must continue parsing because
659                                                  * the opregion is not a standalone package --
660                                                  * we don't know where the end is at this point.
661                                                  *
662                                                  * (Length is unknown until parse of the body complete)
663                                                  */
664
665                                                 deferred_op->data   = aml_op_start;
666                                                 deferred_op->length = 0;
667                                         }
668                                 }
669                         }
670
671
672                         else {
673                                 /* Not a named opcode, just allocate Op and append to parent */
674
675                                 op = acpi_ps_alloc_op (opcode);
676                                 if (!op) {
677                                         return (AE_NO_MEMORY);
678                                 }
679
680
681                                 if ((op->opcode == AML_CREATE_FIELD_OP) ||
682                                         (op->opcode == AML_BIT_FIELD_OP)    ||
683                                         (op->opcode == AML_BYTE_FIELD_OP)   ||
684                                         (op->opcode == AML_WORD_FIELD_OP)   ||
685                                         (op->opcode == AML_DWORD_FIELD_OP)) {
686                                         /*
687                                          * Backup to beginning of Create_xXXfield declaration
688                                          * Body_length is unknown until we parse the body
689                                          */
690                                         deferred_op = (ACPI_PARSE2_OBJECT *) op;
691
692                                         deferred_op->data   = aml_op_start;
693                                         deferred_op->length = 0;
694                                 }
695
696                                 acpi_ps_append_arg (acpi_ps_get_parent_scope (parser_state), op);
697
698                                 if ((walk_state->descending_callback != NULL)) {
699                                         /*
700                                          * Find the object.  This will either insert the object into
701                                          * the namespace or simply look it up
702                                          */
703                                         status = walk_state->descending_callback (opcode, op, walk_state, &op);
704                                         status = acpi_ps_next_parse_state (walk_state, op, status);
705                                         if (status == AE_CTRL_PENDING) {
706                                                 status = AE_OK;
707                                                 goto close_this_op;
708                                         }
709
710                                         if (ACPI_FAILURE (status)) {
711                                                 goto close_this_op;
712                                         }
713                                 }
714                         }
715
716                         op->aml_offset = aml_offset;
717
718                 }
719
720
721                 /* Start Arg_count at zero because we don't know if there are any args yet */
722
723                 arg_count = 0;
724
725
726                 if (arg_types)  /* Are there any arguments that must be processed? */ {
727                         /* get arguments */
728
729                         switch (op->opcode) {
730                         case AML_BYTE_OP:       /* AML_BYTEDATA_ARG */
731                         case AML_WORD_OP:       /* AML_WORDDATA_ARG */
732                         case AML_DWORD_OP:      /* AML_DWORDATA_ARG */
733                         case AML_STRING_OP:     /* AML_ASCIICHARLIST_ARG */
734
735                                 /* fill in constant or string argument directly */
736
737                                 acpi_ps_get_next_simple_arg (parser_state,
738                                                  GET_CURRENT_ARG_TYPE (arg_types), op);
739                                 break;
740
741                         case AML_NAMEPATH_OP:   /* AML_NAMESTRING_ARG */
742
743                                 acpi_ps_get_next_namepath (parser_state, op, &arg_count, 1);
744                                 arg_types = 0;
745                                 break;
746
747
748                         default:
749
750                                 /* Op is not a constant or string, append each argument */
751
752                                 while (GET_CURRENT_ARG_TYPE (arg_types) && !arg_count) {
753                                         aml_offset = parser_state->aml - parser_state->aml_start;
754                                         arg = acpi_ps_get_next_arg (parser_state,
755                                                          GET_CURRENT_ARG_TYPE (arg_types),
756                                                          &arg_count);
757                                         if (arg) {
758                                                 arg->aml_offset = aml_offset;
759                                                 acpi_ps_append_arg (op, arg);
760                                         }
761
762                                         INCREMENT_ARG_LIST (arg_types);
763                                 }
764
765
766                                 /* For a method, save the length and address of the body */
767
768                                 if (op->opcode == AML_METHOD_OP) {
769                                         deferred_op = acpi_ps_to_extended_op (op);
770                                         if (deferred_op) {
771                                                 /*
772                                                  * Skip parsing of control method or opregion body,
773                                                  * because we don't have enough info in the first pass
774                                                  * to parse them correctly.
775                                                  */
776
777                                                 deferred_op->data   = parser_state->aml;
778                                                 deferred_op->length = parser_state->pkg_end -
779                                                                   parser_state->aml;
780
781                                                 /*
782                                                  * Skip body of method.  For Op_regions, we must continue
783                                                  * parsing because the opregion is not a standalone
784                                                  * package (We don't know where the end is).
785                                                  */
786                                                 parser_state->aml   = parser_state->pkg_end;
787                                                 arg_count           = 0;
788                                         }
789                                 }
790
791                                 break;
792                         }
793                 }
794
795
796                 /*
797                  * Zero Arg_count means that all arguments for this op have been processed
798                  */
799                 if (!arg_count) {
800                         /* completed Op, prepare for next */
801
802                         if (acpi_ps_is_named_op (op->opcode)) {
803                                 if (acpi_gbl_depth) {
804                                         acpi_gbl_depth--;
805                                 }
806
807                                 if (op->opcode == AML_REGION_OP) {
808                                         deferred_op = acpi_ps_to_extended_op (op);
809                                         if (deferred_op) {
810                                                 /*
811                                                  * Skip parsing of control method or opregion body,
812                                                  * because we don't have enough info in the first pass
813                                                  * to parse them correctly.
814                                                  *
815                                                  * Completed parsing an Op_region declaration, we now
816                                                  * know the length.
817                                                  */
818
819                                                 deferred_op->length = parser_state->aml -
820                                                                  deferred_op->data;
821                                         }
822                                 }
823                         }
824
825                         if ((op->opcode == AML_CREATE_FIELD_OP) ||
826                                 (op->opcode == AML_BIT_FIELD_OP)    ||
827                                 (op->opcode == AML_BYTE_FIELD_OP)   ||
828                                 (op->opcode == AML_WORD_FIELD_OP)   ||
829                                 (op->opcode == AML_DWORD_FIELD_OP)  ||
830                                 (op->opcode == AML_QWORD_FIELD_OP)) {
831                                 /*
832                                  * Backup to beginning of Create_xXXfield declaration (1 for
833                                  * Opcode)
834                                  *
835                                  * Body_length is unknown until we parse the body
836                                  */
837                                 deferred_op = (ACPI_PARSE2_OBJECT *) op;
838                                 deferred_op->length = parser_state->aml - deferred_op->data;
839                         }
840
841                         /* This op complete, notify the dispatcher */
842
843                         if (walk_state->ascending_callback != NULL) {
844                                 status = walk_state->ascending_callback (walk_state, op);
845                                 status = acpi_ps_next_parse_state (walk_state, op, status);
846                                 if (status == AE_CTRL_PENDING) {
847                                         status = AE_OK;
848                                         goto close_this_op;
849                                 }
850                         }
851
852
853 close_this_op:
854
855                         /*
856                          * Finished one argument of the containing scope
857                          */
858                         parser_state->scope->parse_scope.arg_count--;
859
860                         /* Close this Op (may result in parse subtree deletion) */
861
862                         if (acpi_ps_complete_this_op (walk_state, op)) {
863                                 op = NULL;
864                         }
865
866
867                         switch (status) {
868                         case AE_OK:
869                                 break;
870
871
872                         case AE_CTRL_TRANSFER:
873
874                                 /*
875                                  * We are about to transfer to a called method.
876                                  */
877                                 walk_state->prev_op = op;
878                                 walk_state->prev_arg_types = arg_types;
879                                 return (status);
880                                 break;
881
882
883                         case AE_CTRL_END:
884
885                                 acpi_ps_pop_scope (parser_state, &op, &arg_types, &arg_count);
886
887                                 status = walk_state->ascending_callback (walk_state, op);
888                                 status = acpi_ps_next_parse_state (walk_state, op, status);
889
890                                 acpi_ps_complete_this_op (walk_state, op);
891                                 op = NULL;
892                                 status = AE_OK;
893                                 break;
894
895
896                         case AE_CTRL_TERMINATE:
897
898                                 status = AE_OK;
899
900                                 /* Clean up */
901                                 do {
902                                         if (op) {
903                                                 acpi_ps_complete_this_op (walk_state, op);
904                                         }
905
906                                         acpi_ps_pop_scope (parser_state, &op, &arg_types, &arg_count);
907                                 } while (op);
908
909                                 return (status);
910                                 break;
911
912
913                         default:  /* All other non-AE_OK status */
914
915                                 if (op == NULL) {
916                                         acpi_ps_pop_scope (parser_state, &op, &arg_types, &arg_count);
917                                 }
918                                 walk_state->prev_op = op;
919                                 walk_state->prev_arg_types = arg_types;
920
921                                 /*
922                                  * TEMP:
923                                  */
924
925                                 return (status);
926                                 break;
927                         }
928
929
930                         /* This scope complete? */
931
932                         if (acpi_ps_has_completed_scope (parser_state)) {
933                                 acpi_ps_pop_scope (parser_state, &op, &arg_types, &arg_count);
934                         }
935
936                         else {
937                                 op = NULL;
938                         }
939
940                 }
941
942
943                 /* Arg_count is non-zero */
944
945                 else {
946                         /* complex argument, push Op and prepare for argument */
947
948                         acpi_ps_push_scope (parser_state, op, arg_types, arg_count);
949                         op = NULL;
950                 }
951
952         } /* while Parser_state->Aml */
953
954
955         /*
956          * Complete the last Op (if not completed), and clear the scope stack.
957          * It is easily possible to end an AML "package" with an unbounded number
958          * of open scopes (such as when several AML blocks are closed with
959          * sequential closing braces).  We want to terminate each one cleanly.
960          */
961
962         do {
963                 if (op) {
964                         if (walk_state->ascending_callback != NULL) {
965                                 status = walk_state->ascending_callback (walk_state, op);
966                                 status = acpi_ps_next_parse_state (walk_state, op, status);
967                                 if (status == AE_CTRL_PENDING) {
968                                         status = AE_OK;
969                                         goto close_this_op;
970                                 }
971
972                                 if (status == AE_CTRL_TERMINATE) {
973                                         status = AE_OK;
974
975                                         /* Clean up */
976                                         do {
977                                                 if (op) {
978                                                         acpi_ps_complete_this_op (walk_state, op);
979                                                 }
980
981                                                 acpi_ps_pop_scope (parser_state, &op, &arg_types, &arg_count);
982
983                                         } while (op);
984
985                                         return (status);
986                                 }
987
988                                 else if (ACPI_FAILURE (status)) {
989                                         acpi_ps_complete_this_op (walk_state, op);
990                                         return (status);
991                                 }
992                         }
993
994                         acpi_ps_complete_this_op (walk_state, op);
995                 }
996
997                 acpi_ps_pop_scope (parser_state, &op, &arg_types, &arg_count);
998
999         } while (op);
1000
1001         return (status);
1002 }
1003
1004
1005 /*******************************************************************************
1006  *
1007  * FUNCTION:    Acpi_ps_parse_aml
1008  *
1009  * PARAMETERS:  Start_scope     - The starting point of the parse.  Becomes the
1010  *                                root of the parsed op tree.
1011  *              Aml             - Pointer to the raw AML code to parse
1012  *              Aml_size        - Length of the AML to parse
1013  *
1014  * RETURN:      Status
1015  *
1016  * DESCRIPTION: Parse raw AML and return a tree of ops
1017  *
1018  ******************************************************************************/
1019
1020 ACPI_STATUS
1021 acpi_ps_parse_aml (
1022         ACPI_PARSE_OBJECT       *start_scope,
1023         u8                      *aml,
1024         u32                     aml_size,
1025         u32                     parse_flags,
1026         ACPI_NAMESPACE_NODE     *method_node,
1027         ACPI_OPERAND_OBJECT     **params,
1028         ACPI_OPERAND_OBJECT     **caller_return_desc,
1029         ACPI_PARSE_DOWNWARDS    descending_callback,
1030         ACPI_PARSE_UPWARDS      ascending_callback)
1031 {
1032         ACPI_STATUS             status;
1033         ACPI_PARSE_STATE        *parser_state;
1034         ACPI_WALK_STATE         *walk_state;
1035         ACPI_WALK_LIST          walk_list;
1036         ACPI_NAMESPACE_NODE     *node = NULL;
1037         ACPI_WALK_LIST          *prev_walk_list = acpi_gbl_current_walk_list;
1038         ACPI_OPERAND_OBJECT     *return_desc;
1039         ACPI_OPERAND_OBJECT     *mth_desc = NULL;
1040
1041
1042         /* Create and initialize a new parser state */
1043
1044         parser_state = acpi_ps_create_state (aml, aml_size);
1045         if (!parser_state) {
1046                 return (AE_NO_MEMORY);
1047         }
1048
1049         acpi_ps_init_scope (parser_state, start_scope);
1050
1051         if (method_node) {
1052                 mth_desc = acpi_ns_get_attached_object (method_node);
1053         }
1054
1055         /* Create and initialize a new walk list */
1056
1057         walk_list.walk_state = NULL;
1058         walk_list.acquired_mutex_list.prev = NULL;
1059         walk_list.acquired_mutex_list.next = NULL;
1060
1061         walk_state = acpi_ds_create_walk_state (TABLE_ID_DSDT, parser_state->start_op, mth_desc, &walk_list);
1062         if (!walk_state) {
1063                 status = AE_NO_MEMORY;
1064                 goto cleanup;
1065         }
1066
1067         walk_state->method_node         = method_node;
1068         walk_state->parser_state        = parser_state;
1069         walk_state->parse_flags         = parse_flags;
1070         walk_state->descending_callback = descending_callback;
1071         walk_state->ascending_callback  = ascending_callback;
1072
1073         /* TBD: [Restructure] TEMP until we pass Walk_state to the interpreter
1074          */
1075         acpi_gbl_current_walk_list = &walk_list;
1076
1077
1078         if (method_node) {
1079                 parser_state->start_node = method_node;
1080                 walk_state->walk_type   = WALK_METHOD;
1081
1082                 /* Push start scope on scope stack and make it current  */
1083
1084                 status = acpi_ds_scope_stack_push (method_node, ACPI_TYPE_METHOD, walk_state);
1085                 if (ACPI_FAILURE (status)) {
1086                         return (status);
1087                 }
1088
1089                 /* Init arguments if this is a control method */
1090                 /* TBD: [Restructure] add walkstate as a param */
1091
1092                 acpi_ds_method_data_init_args (params, MTH_NUM_ARGS, walk_state);
1093         }
1094
1095         else {
1096                 /* Setup the current scope */
1097
1098                 node = parser_state->start_op->node;
1099                 parser_state->start_node = node;
1100
1101                 if (node) {
1102                         /* Push start scope on scope stack and make it current  */
1103
1104                         status = acpi_ds_scope_stack_push (node, node->type,
1105                                            walk_state);
1106                         if (ACPI_FAILURE (status)) {
1107                                 goto cleanup;
1108                         }
1109
1110                 }
1111         }
1112
1113
1114         status = AE_OK;
1115
1116         /*
1117          * Execute the walk loop as long as there is a valid Walk State.  This
1118          * handles nested control method invocations without recursion.
1119          */
1120
1121         while (walk_state) {
1122                 if (ACPI_SUCCESS (status)) {
1123                         status = acpi_ps_parse_loop (walk_state);
1124                 }
1125
1126                 if (status == AE_CTRL_TRANSFER) {
1127                         /*
1128                          * A method call was detected.
1129                          * Transfer control to the called control method
1130                          */
1131
1132                         status = acpi_ds_call_control_method (&walk_list, walk_state, NULL);
1133
1134                         /*
1135                          * If the transfer to the new method method call worked, a new walk
1136                          * state was created -- get it
1137                          */
1138
1139                         walk_state = acpi_ds_get_current_walk_state (&walk_list);
1140                         continue;
1141                 }
1142
1143                 else if (status == AE_CTRL_TERMINATE) {
1144                         status = AE_OK;
1145                 }
1146
1147                 /* We are done with this walk, move on to the parent if any */
1148
1149
1150                 walk_state = acpi_ds_pop_walk_state (&walk_list);
1151
1152                 /* Extract return value before we delete Walk_state */
1153
1154                 return_desc = walk_state->return_desc;
1155
1156                 /* Reset the current scope to the beginning of scope stack */
1157
1158                 acpi_ds_scope_stack_clear (walk_state);
1159
1160                 /*
1161                  * If we just returned from the execution of a control method,
1162                  * there's lots of cleanup to do
1163                  */
1164
1165                 if ((walk_state->parse_flags & ACPI_PARSE_MODE_MASK) == ACPI_PARSE_EXECUTE) {
1166                         acpi_ds_terminate_control_method (walk_state);
1167                 }
1168
1169                  /* Delete this walk state and all linked control states */
1170
1171                 acpi_ps_cleanup_scope (walk_state->parser_state);
1172                 acpi_cm_free (walk_state->parser_state);
1173                 acpi_ds_delete_walk_state (walk_state);
1174
1175            /* Check if we have restarted a preempted walk */
1176
1177                 walk_state = acpi_ds_get_current_walk_state (&walk_list);
1178                 if (walk_state &&
1179                         ACPI_SUCCESS (status)) {
1180                         /* There is another walk state, restart it */
1181
1182                         /*
1183                          * If the method returned value is not used by the parent,
1184                          * The object is deleted
1185                          */
1186
1187                         acpi_ds_restart_control_method (walk_state, return_desc);
1188                         walk_state->walk_type |= WALK_METHOD_RESTART;
1189                 }
1190
1191                 /*
1192                  * Just completed a 1st-level method, save the final internal return
1193                  * value (if any)
1194                  */
1195
1196                 else if (caller_return_desc) {
1197                         *caller_return_desc = return_desc; /* NULL if no return value */
1198                 }
1199
1200                 else if (return_desc) {
1201                         /* Caller doesn't want it, must delete it */
1202
1203                         acpi_cm_remove_reference (return_desc);
1204                 }
1205         }
1206
1207
1208         /* Normal exit */
1209
1210         acpi_aml_release_all_mutexes ((ACPI_OPERAND_OBJECT *) &walk_list.acquired_mutex_list);
1211         acpi_gbl_current_walk_list = prev_walk_list;
1212         return (status);
1213
1214
1215 cleanup:
1216
1217         /* Cleanup */
1218
1219         acpi_ds_delete_walk_state (walk_state);
1220         acpi_ps_cleanup_scope (parser_state);
1221         acpi_cm_free (parser_state);
1222
1223         acpi_aml_release_all_mutexes ((ACPI_OPERAND_OBJECT *)&walk_list.acquired_mutex_list);
1224         acpi_gbl_current_walk_list = prev_walk_list;
1225
1226         return (status);
1227 }
1228
1229