1 /******************************************************************************
2  *
3  * Module Name: psobject - Support for parse objects
4  *
5  *****************************************************************************/
6 
7 /******************************************************************************
8  *
9  * 1. Copyright Notice
10  *
11  * Some or all of this work - Copyright (c) 1999 - 2017, Intel Corp.
12  * All rights reserved.
13  *
14  * 2. License
15  *
16  * 2.1. This is your license from Intel Corp. under its intellectual property
17  * rights. You may have additional license terms from the party that provided
18  * you this software, covering your right to use that party's intellectual
19  * property rights.
20  *
21  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
22  * copy of the source code appearing in this file ("Covered Code") an
23  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
24  * base code distributed originally by Intel ("Original Intel Code") to copy,
25  * make derivatives, distribute, use and display any portion of the Covered
26  * Code in any form, with the right to sublicense such rights; and
27  *
28  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
29  * license (with the right to sublicense), under only those claims of Intel
30  * patents that are infringed by the Original Intel Code, to make, use, sell,
31  * offer to sell, and import the Covered Code and derivative works thereof
32  * solely to the minimum extent necessary to exercise the above copyright
33  * license, and in no event shall the patent license extend to any additions
34  * to or modifications of the Original Intel Code. No other license or right
35  * is granted directly or by implication, estoppel or otherwise;
36  *
37  * The above copyright and patent license is granted only if the following
38  * conditions are met:
39  *
40  * 3. Conditions
41  *
42  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
43  * Redistribution of source code of any substantial portion of the Covered
44  * Code or modification with rights to further distribute source must include
45  * the above Copyright Notice, the above License, this list of Conditions,
46  * and the following Disclaimer and Export Compliance provision. In addition,
47  * Licensee must cause all Covered Code to which Licensee contributes to
48  * contain a file documenting the changes Licensee made to create that Covered
49  * Code and the date of any change. Licensee must include in that file the
50  * documentation of any changes made by any predecessor Licensee. Licensee
51  * must include a prominent statement that the modification is derived,
52  * directly or indirectly, from Original Intel Code.
53  *
54  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
55  * Redistribution of source code of any substantial portion of the Covered
56  * Code or modification without rights to further distribute source must
57  * include the following Disclaimer and Export Compliance provision in the
58  * documentation and/or other materials provided with distribution. In
59  * addition, Licensee may not authorize further sublicense of source of any
60  * portion of the Covered Code, and must include terms to the effect that the
61  * license from Licensee to its licensee is limited to the intellectual
62  * property embodied in the software Licensee provides to its licensee, and
63  * not to intellectual property embodied in modifications its licensee may
64  * make.
65  *
66  * 3.3. Redistribution of Executable. Redistribution in executable form of any
67  * substantial portion of the Covered Code or modification must reproduce the
68  * above Copyright Notice, and the following Disclaimer and Export Compliance
69  * provision in the documentation and/or other materials provided with the
70  * distribution.
71  *
72  * 3.4. Intel retains all right, title, and interest in and to the Original
73  * Intel Code.
74  *
75  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
76  * Intel shall be used in advertising or otherwise to promote the sale, use or
77  * other dealings in products derived from or relating to the Covered Code
78  * without prior written authorization from Intel.
79  *
80  * 4. Disclaimer and Export Compliance
81  *
82  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
83  * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
84  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
85  * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
86  * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
87  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
88  * PARTICULAR PURPOSE.
89  *
90  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
91  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
92  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
93  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
94  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
95  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
96  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
97  * LIMITED REMEDY.
98  *
99  * 4.3. Licensee shall not export, either directly or indirectly, any of this
100  * software or system incorporating such software without first obtaining any
101  * required license or other approval from the U. S. Department of Commerce or
102  * any other agency or department of the United States Government. In the
103  * event Licensee exports any such software from the United States or
104  * re-exports any such software from a foreign destination, Licensee shall
105  * ensure that the distribution and export/re-export of the software is in
106  * compliance with all laws, regulations, orders, or other restrictions of the
107  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
108  * any of its subsidiaries will export/re-export any technical data, process,
109  * software, or service, directly or indirectly, to any country for which the
110  * United States government or any agency thereof requires an export license,
111  * other governmental approval, or letter of assurance, without first obtaining
112  * such license, approval or letter.
113  *
114  *****************************************************************************
115  *
116  * Alternatively, you may choose to be licensed under the terms of the
117  * following license:
118  *
119  * Redistribution and use in source and binary forms, with or without
120  * modification, are permitted provided that the following conditions
121  * are met:
122  * 1. Redistributions of source code must retain the above copyright
123  *    notice, this list of conditions, and the following disclaimer,
124  *    without modification.
125  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
126  *    substantially similar to the "NO WARRANTY" disclaimer below
127  *    ("Disclaimer") and any redistribution must be conditioned upon
128  *    including a substantially similar Disclaimer requirement for further
129  *    binary redistribution.
130  * 3. Neither the names of the above-listed copyright holders nor the names
131  *    of any contributors may be used to endorse or promote products derived
132  *    from this software without specific prior written permission.
133  *
134  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
135  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
136  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
137  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
138  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
139  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
140  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
141  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
142  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
143  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
144  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
145  *
146  * Alternatively, you may choose to be licensed under the terms of the
147  * GNU General Public License ("GPL") version 2 as published by the Free
148  * Software Foundation.
149  *
150  *****************************************************************************/
151 
152 #include <contrib/dev/acpica/include/acpi.h>
153 #include <contrib/dev/acpica/include/accommon.h>
154 #include <contrib/dev/acpica/include/acparser.h>
155 #include <contrib/dev/acpica/include/amlcode.h>
156 #include <contrib/dev/acpica/include/acconvert.h>
157 
158 #define _COMPONENT          ACPI_PARSER
159         ACPI_MODULE_NAME    ("psobject")
160 
161 
162 /* Local prototypes */
163 
164 static ACPI_STATUS
165 AcpiPsGetAmlOpcode (
166     ACPI_WALK_STATE         *WalkState);
167 
168 
169 /*******************************************************************************
170  *
171  * FUNCTION:    AcpiPsGetAmlOpcode
172  *
173  * PARAMETERS:  WalkState           - Current state
174  *
175  * RETURN:      Status
176  *
177  * DESCRIPTION: Extract the next AML opcode from the input stream.
178  *
179  ******************************************************************************/
180 
181 static ACPI_STATUS
182 AcpiPsGetAmlOpcode (
183     ACPI_WALK_STATE         *WalkState)
184 {
185     UINT32                  AmlOffset;
186 
187 
188     ACPI_FUNCTION_TRACE_PTR (PsGetAmlOpcode, WalkState);
189 
190 
191     WalkState->Aml = WalkState->ParserState.Aml;
192     WalkState->Opcode = AcpiPsPeekOpcode (&(WalkState->ParserState));
193 
194     /*
195      * First cut to determine what we have found:
196      * 1) A valid AML opcode
197      * 2) A name string
198      * 3) An unknown/invalid opcode
199      */
200     WalkState->OpInfo = AcpiPsGetOpcodeInfo (WalkState->Opcode);
201 
202     switch (WalkState->OpInfo->Class)
203     {
204     case AML_CLASS_ASCII:
205     case AML_CLASS_PREFIX:
206         /*
207          * Starts with a valid prefix or ASCII char, this is a name
208          * string. Convert the bare name string to a namepath.
209          */
210         WalkState->Opcode = AML_INT_NAMEPATH_OP;
211         WalkState->ArgTypes = ARGP_NAMESTRING;
212         break;
213 
214     case AML_CLASS_UNKNOWN:
215 
216         /* The opcode is unrecognized. Complain and skip unknown opcodes */
217 
218         if (WalkState->PassNumber == 2)
219         {
220             AmlOffset = (UINT32) ACPI_PTR_DIFF (WalkState->Aml,
221                 WalkState->ParserState.AmlStart);
222 
223             ACPI_ERROR ((AE_INFO,
224                 "Unknown opcode 0x%.2X at table offset 0x%.4X, ignoring",
225                 WalkState->Opcode,
226                 (UINT32) (AmlOffset + sizeof (ACPI_TABLE_HEADER))));
227 
228             ACPI_DUMP_BUFFER ((WalkState->ParserState.Aml - 16), 48);
229 
230 #ifdef ACPI_ASL_COMPILER
231             /*
232              * This is executed for the disassembler only. Output goes
233              * to the disassembled ASL output file.
234              */
235             AcpiOsPrintf (
236                 "/*\nError: Unknown opcode 0x%.2X at table offset 0x%.4X, context:\n",
237                 WalkState->Opcode,
238                 (UINT32) (AmlOffset + sizeof (ACPI_TABLE_HEADER)));
239 
240             /* Dump the context surrounding the invalid opcode */
241 
242             AcpiUtDumpBuffer (((UINT8 *) WalkState->ParserState.Aml - 16),
243                 48, DB_BYTE_DISPLAY,
244                 (AmlOffset + sizeof (ACPI_TABLE_HEADER) - 16));
245             AcpiOsPrintf (" */\n");
246 #endif
247         }
248 
249         /* Increment past one-byte or two-byte opcode */
250 
251         WalkState->ParserState.Aml++;
252         if (WalkState->Opcode > 0xFF) /* Can only happen if first byte is 0x5B */
253         {
254             WalkState->ParserState.Aml++;
255         }
256 
257         return_ACPI_STATUS (AE_CTRL_PARSE_CONTINUE);
258 
259     default:
260 
261         /* Found opcode info, this is a normal opcode */
262 
263         WalkState->ParserState.Aml +=
264             AcpiPsGetOpcodeSize (WalkState->Opcode);
265         WalkState->ArgTypes = WalkState->OpInfo->ParseArgs;
266         break;
267     }
268 
269     return_ACPI_STATUS (AE_OK);
270 }
271 
272 
273 /*******************************************************************************
274  *
275  * FUNCTION:    AcpiPsBuildNamedOp
276  *
277  * PARAMETERS:  WalkState           - Current state
278  *              AmlOpStart          - Begin of named Op in AML
279  *              UnnamedOp           - Early Op (not a named Op)
280  *              Op                  - Returned Op
281  *
282  * RETURN:      Status
283  *
284  * DESCRIPTION: Parse a named Op
285  *
286  ******************************************************************************/
287 
288 ACPI_STATUS
289 AcpiPsBuildNamedOp (
290     ACPI_WALK_STATE         *WalkState,
291     UINT8                   *AmlOpStart,
292     ACPI_PARSE_OBJECT       *UnnamedOp,
293     ACPI_PARSE_OBJECT       **Op)
294 {
295     ACPI_STATUS             Status = AE_OK;
296     ACPI_PARSE_OBJECT       *Arg = NULL;
297 
298 
299     ACPI_FUNCTION_TRACE_PTR (PsBuildNamedOp, WalkState);
300 
301 
302     UnnamedOp->Common.Value.Arg = NULL;
303     UnnamedOp->Common.ArgListLength = 0;
304     UnnamedOp->Common.AmlOpcode = WalkState->Opcode;
305 
306     /*
307      * Get and append arguments until we find the node that contains
308      * the name (the type ARGP_NAME).
309      */
310     while (GET_CURRENT_ARG_TYPE (WalkState->ArgTypes) &&
311           (GET_CURRENT_ARG_TYPE (WalkState->ArgTypes) != ARGP_NAME))
312     {
313         ASL_CV_CAPTURE_COMMENTS (WalkState);
314         Status = AcpiPsGetNextArg (WalkState, &(WalkState->ParserState),
315             GET_CURRENT_ARG_TYPE (WalkState->ArgTypes), &Arg);
316         if (ACPI_FAILURE (Status))
317         {
318             return_ACPI_STATUS (Status);
319         }
320 
321         AcpiPsAppendArg (UnnamedOp, Arg);
322         INCREMENT_ARG_LIST (WalkState->ArgTypes);
323     }
324 
325     /* are there any inline comments associated with the NameSeg?? If so, save this. */
326 
327     ASL_CV_CAPTURE_COMMENTS (WalkState);
328 
329 #ifdef ACPI_ASL_COMPILER
330     if (AcpiGbl_CurrentInlineComment != NULL)
331     {
332         UnnamedOp->Common.NameComment = AcpiGbl_CurrentInlineComment;
333         AcpiGbl_CurrentInlineComment = NULL;
334     }
335 #endif
336 
337     /*
338      * Make sure that we found a NAME and didn't run out of arguments
339      */
340     if (!GET_CURRENT_ARG_TYPE (WalkState->ArgTypes))
341     {
342         return_ACPI_STATUS (AE_AML_NO_OPERAND);
343     }
344 
345     /* We know that this arg is a name, move to next arg */
346 
347     INCREMENT_ARG_LIST (WalkState->ArgTypes);
348 
349     /*
350      * Find the object. This will either insert the object into
351      * the namespace or simply look it up
352      */
353     WalkState->Op = NULL;
354 
355     Status = WalkState->DescendingCallback (WalkState, Op);
356     if (ACPI_FAILURE (Status))
357     {
358         if (Status != AE_CTRL_TERMINATE)
359         {
360             ACPI_EXCEPTION ((AE_INFO, Status, "During name lookup/catalog"));
361         }
362         return_ACPI_STATUS (Status);
363     }
364 
365     if (!*Op)
366     {
367         return_ACPI_STATUS (AE_CTRL_PARSE_CONTINUE);
368     }
369 
370     Status = AcpiPsNextParseState (WalkState, *Op, Status);
371     if (ACPI_FAILURE (Status))
372     {
373         if (Status == AE_CTRL_PENDING)
374         {
375             Status = AE_CTRL_PARSE_PENDING;
376         }
377         return_ACPI_STATUS (Status);
378     }
379 
380     AcpiPsAppendArg (*Op, UnnamedOp->Common.Value.Arg);
381 
382 #ifdef ACPI_ASL_COMPILER
383 
384     /* save any comments that might be associated with UnnamedOp. */
385 
386     (*Op)->Common.InlineComment     = UnnamedOp->Common.InlineComment;
387     (*Op)->Common.EndNodeComment    = UnnamedOp->Common.EndNodeComment;
388     (*Op)->Common.CloseBraceComment = UnnamedOp->Common.CloseBraceComment;
389     (*Op)->Common.NameComment       = UnnamedOp->Common.NameComment;
390     (*Op)->Common.CommentList       = UnnamedOp->Common.CommentList;
391     (*Op)->Common.EndBlkComment     = UnnamedOp->Common.EndBlkComment;
392     (*Op)->Common.CvFilename        = UnnamedOp->Common.CvFilename;
393     (*Op)->Common.CvParentFilename  = UnnamedOp->Common.CvParentFilename;
394     (*Op)->Named.Aml                = UnnamedOp->Common.Aml;
395 
396     UnnamedOp->Common.InlineComment     = NULL;
397     UnnamedOp->Common.EndNodeComment    = NULL;
398     UnnamedOp->Common.CloseBraceComment = NULL;
399     UnnamedOp->Common.NameComment       = NULL;
400     UnnamedOp->Common.CommentList       = NULL;
401     UnnamedOp->Common.EndBlkComment     = NULL;
402 #endif
403 
404     if ((*Op)->Common.AmlOpcode == AML_REGION_OP ||
405         (*Op)->Common.AmlOpcode == AML_DATA_REGION_OP)
406     {
407         /*
408          * Defer final parsing of an OperationRegion body, because we don't
409          * have enough info in the first pass to parse it correctly (i.e.,
410          * there may be method calls within the TermArg elements of the body.)
411          *
412          * However, we must continue parsing because the opregion is not a
413          * standalone package -- we don't know where the end is at this point.
414          *
415          * (Length is unknown until parse of the body complete)
416          */
417         (*Op)->Named.Data = AmlOpStart;
418         (*Op)->Named.Length = 0;
419     }
420 
421     return_ACPI_STATUS (AE_OK);
422 }
423 
424 
425 /*******************************************************************************
426  *
427  * FUNCTION:    AcpiPsCreateOp
428  *
429  * PARAMETERS:  WalkState           - Current state
430  *              AmlOpStart          - Op start in AML
431  *              NewOp               - Returned Op
432  *
433  * RETURN:      Status
434  *
435  * DESCRIPTION: Get Op from AML
436  *
437  ******************************************************************************/
438 
439 ACPI_STATUS
440 AcpiPsCreateOp (
441     ACPI_WALK_STATE         *WalkState,
442     UINT8                   *AmlOpStart,
443     ACPI_PARSE_OBJECT       **NewOp)
444 {
445     ACPI_STATUS             Status = AE_OK;
446     ACPI_PARSE_OBJECT       *Op;
447     ACPI_PARSE_OBJECT       *NamedOp = NULL;
448     ACPI_PARSE_OBJECT       *ParentScope;
449     UINT8                   ArgumentCount;
450     const ACPI_OPCODE_INFO  *OpInfo;
451 
452 
453     ACPI_FUNCTION_TRACE_PTR (PsCreateOp, WalkState);
454 
455 
456     Status = AcpiPsGetAmlOpcode (WalkState);
457     if (Status == AE_CTRL_PARSE_CONTINUE)
458     {
459         return_ACPI_STATUS (AE_CTRL_PARSE_CONTINUE);
460     }
461 
462     /* Create Op structure and append to parent's argument list */
463 
464     WalkState->OpInfo = AcpiPsGetOpcodeInfo (WalkState->Opcode);
465     Op = AcpiPsAllocOp (WalkState->Opcode, AmlOpStart);
466     if (!Op)
467     {
468         return_ACPI_STATUS (AE_NO_MEMORY);
469     }
470 
471     if (WalkState->OpInfo->Flags & AML_NAMED)
472     {
473         Status = AcpiPsBuildNamedOp (WalkState, AmlOpStart, Op, &NamedOp);
474         AcpiPsFreeOp (Op);
475         if (ACPI_FAILURE (Status))
476         {
477             return_ACPI_STATUS (Status);
478         }
479 
480         *NewOp = NamedOp;
481         return_ACPI_STATUS (AE_OK);
482     }
483 
484     /* Not a named opcode, just allocate Op and append to parent */
485 
486     if (WalkState->OpInfo->Flags & AML_CREATE)
487     {
488         /*
489          * Backup to beginning of CreateXXXfield declaration
490          * BodyLength is unknown until we parse the body
491          */
492         Op->Named.Data = AmlOpStart;
493         Op->Named.Length = 0;
494     }
495 
496     if (WalkState->Opcode == AML_BANK_FIELD_OP)
497     {
498         /*
499          * Backup to beginning of BankField declaration
500          * BodyLength is unknown until we parse the body
501          */
502         Op->Named.Data = AmlOpStart;
503         Op->Named.Length = 0;
504     }
505 
506     ParentScope = AcpiPsGetParentScope (&(WalkState->ParserState));
507     AcpiPsAppendArg (ParentScope, Op);
508 
509     if (ParentScope)
510     {
511         OpInfo = AcpiPsGetOpcodeInfo (ParentScope->Common.AmlOpcode);
512         if (OpInfo->Flags & AML_HAS_TARGET)
513         {
514             ArgumentCount = AcpiPsGetArgumentCount (OpInfo->Type);
515             if (ParentScope->Common.ArgListLength > ArgumentCount)
516             {
517                 Op->Common.Flags |= ACPI_PARSEOP_TARGET;
518             }
519         }
520 
521         /*
522          * Special case for both Increment() and Decrement(), where
523          * the lone argument is both a source and a target.
524          */
525         else if ((ParentScope->Common.AmlOpcode == AML_INCREMENT_OP) ||
526                 (ParentScope->Common.AmlOpcode == AML_DECREMENT_OP))
527         {
528             Op->Common.Flags |= ACPI_PARSEOP_TARGET;
529         }
530     }
531 
532     if (WalkState->DescendingCallback != NULL)
533     {
534         /*
535          * Find the object. This will either insert the object into
536          * the namespace or simply look it up
537          */
538         WalkState->Op = *NewOp = Op;
539 
540         Status = WalkState->DescendingCallback (WalkState, &Op);
541         Status = AcpiPsNextParseState (WalkState, Op, Status);
542         if (Status == AE_CTRL_PENDING)
543         {
544             Status = AE_CTRL_PARSE_PENDING;
545         }
546     }
547 
548     return_ACPI_STATUS (Status);
549 }
550 
551 
552 /*******************************************************************************
553  *
554  * FUNCTION:    AcpiPsCompleteOp
555  *
556  * PARAMETERS:  WalkState           - Current state
557  *              Op                  - Returned Op
558  *              Status              - Parse status before complete Op
559  *
560  * RETURN:      Status
561  *
562  * DESCRIPTION: Complete Op
563  *
564  ******************************************************************************/
565 
566 ACPI_STATUS
567 AcpiPsCompleteOp (
568     ACPI_WALK_STATE         *WalkState,
569     ACPI_PARSE_OBJECT       **Op,
570     ACPI_STATUS             Status)
571 {
572     ACPI_STATUS             Status2;
573 
574 
575     ACPI_FUNCTION_TRACE_PTR (PsCompleteOp, WalkState);
576 
577 
578     /*
579      * Finished one argument of the containing scope
580      */
581     WalkState->ParserState.Scope->ParseScope.ArgCount--;
582 
583     /* Close this Op (will result in parse subtree deletion) */
584 
585     Status2 = AcpiPsCompleteThisOp (WalkState, *Op);
586     if (ACPI_FAILURE (Status2))
587     {
588         return_ACPI_STATUS (Status2);
589     }
590 
591     *Op = NULL;
592 
593     switch (Status)
594     {
595     case AE_OK:
596 
597         break;
598 
599     case AE_CTRL_TRANSFER:
600 
601         /* We are about to transfer to a called method */
602 
603         WalkState->PrevOp = NULL;
604         WalkState->PrevArgTypes = WalkState->ArgTypes;
605         return_ACPI_STATUS (Status);
606 
607     case AE_CTRL_END:
608 
609         AcpiPsPopScope (&(WalkState->ParserState), Op,
610             &WalkState->ArgTypes, &WalkState->ArgCount);
611 
612         if (*Op)
613         {
614             WalkState->Op = *Op;
615             WalkState->OpInfo = AcpiPsGetOpcodeInfo ((*Op)->Common.AmlOpcode);
616             WalkState->Opcode = (*Op)->Common.AmlOpcode;
617 
618             Status = WalkState->AscendingCallback (WalkState);
619             Status = AcpiPsNextParseState (WalkState, *Op, Status);
620 
621             Status2 = AcpiPsCompleteThisOp (WalkState, *Op);
622             if (ACPI_FAILURE (Status2))
623             {
624                 return_ACPI_STATUS (Status2);
625             }
626         }
627 
628         Status = AE_OK;
629         break;
630 
631     case AE_CTRL_BREAK:
632     case AE_CTRL_CONTINUE:
633 
634         /* Pop off scopes until we find the While */
635 
636         while (!(*Op) || ((*Op)->Common.AmlOpcode != AML_WHILE_OP))
637         {
638             AcpiPsPopScope (&(WalkState->ParserState), Op,
639                 &WalkState->ArgTypes, &WalkState->ArgCount);
640         }
641 
642         /* Close this iteration of the While loop */
643 
644         WalkState->Op = *Op;
645         WalkState->OpInfo = AcpiPsGetOpcodeInfo ((*Op)->Common.AmlOpcode);
646         WalkState->Opcode = (*Op)->Common.AmlOpcode;
647 
648         Status = WalkState->AscendingCallback (WalkState);
649         Status = AcpiPsNextParseState (WalkState, *Op, Status);
650 
651         Status2 = AcpiPsCompleteThisOp (WalkState, *Op);
652         if (ACPI_FAILURE (Status2))
653         {
654             return_ACPI_STATUS (Status2);
655         }
656 
657         Status = AE_OK;
658         break;
659 
660     case AE_CTRL_TERMINATE:
661 
662         /* Clean up */
663         do
664         {
665             if (*Op)
666             {
667                 Status2 = AcpiPsCompleteThisOp (WalkState, *Op);
668                 if (ACPI_FAILURE (Status2))
669                 {
670                     return_ACPI_STATUS (Status2);
671                 }
672 
673                 AcpiUtDeleteGenericState (
674                     AcpiUtPopGenericState (&WalkState->ControlState));
675             }
676 
677             AcpiPsPopScope (&(WalkState->ParserState), Op,
678                 &WalkState->ArgTypes, &WalkState->ArgCount);
679 
680         } while (*Op);
681 
682         return_ACPI_STATUS (AE_OK);
683 
684     default:  /* All other non-AE_OK status */
685 
686         do
687         {
688             if (*Op)
689             {
690                 Status2 = AcpiPsCompleteThisOp (WalkState, *Op);
691                 if (ACPI_FAILURE (Status2))
692                 {
693                     return_ACPI_STATUS (Status2);
694                 }
695             }
696 
697             AcpiPsPopScope (&(WalkState->ParserState), Op,
698                 &WalkState->ArgTypes, &WalkState->ArgCount);
699 
700         } while (*Op);
701 
702 
703 #if 0
704         /*
705          * TBD: Cleanup parse ops on error
706          */
707         if (*Op == NULL)
708         {
709             AcpiPsPopScope (ParserState, Op,
710                 &WalkState->ArgTypes, &WalkState->ArgCount);
711         }
712 #endif
713         WalkState->PrevOp = NULL;
714         WalkState->PrevArgTypes = WalkState->ArgTypes;
715         return_ACPI_STATUS (Status);
716     }
717 
718     /* This scope complete? */
719 
720     if (AcpiPsHasCompletedScope (&(WalkState->ParserState)))
721     {
722         AcpiPsPopScope (&(WalkState->ParserState), Op,
723             &WalkState->ArgTypes, &WalkState->ArgCount);
724         ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Popped scope, Op=%p\n", *Op));
725     }
726     else
727     {
728         *Op = NULL;
729     }
730 
731     return_ACPI_STATUS (AE_OK);
732 }
733 
734 
735 /*******************************************************************************
736  *
737  * FUNCTION:    AcpiPsCompleteFinalOp
738  *
739  * PARAMETERS:  WalkState           - Current state
740  *              Op                  - Current Op
741  *              Status              - Current parse status before complete last
742  *                                    Op
743  *
744  * RETURN:      Status
745  *
746  * DESCRIPTION: Complete last Op.
747  *
748  ******************************************************************************/
749 
750 ACPI_STATUS
751 AcpiPsCompleteFinalOp (
752     ACPI_WALK_STATE         *WalkState,
753     ACPI_PARSE_OBJECT       *Op,
754     ACPI_STATUS             Status)
755 {
756     ACPI_STATUS             Status2;
757 
758 
759     ACPI_FUNCTION_TRACE_PTR (PsCompleteFinalOp, WalkState);
760 
761 
762     /*
763      * Complete the last Op (if not completed), and clear the scope stack.
764      * It is easily possible to end an AML "package" with an unbounded number
765      * of open scopes (such as when several ASL blocks are closed with
766      * sequential closing braces). We want to terminate each one cleanly.
767      */
768     ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "AML package complete at Op %p\n", Op));
769     do
770     {
771         if (Op)
772         {
773             if (WalkState->AscendingCallback != NULL)
774             {
775                 WalkState->Op = Op;
776                 WalkState->OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
777                 WalkState->Opcode = Op->Common.AmlOpcode;
778 
779                 Status = WalkState->AscendingCallback (WalkState);
780                 Status = AcpiPsNextParseState (WalkState, Op, Status);
781                 if (Status == AE_CTRL_PENDING)
782                 {
783                     Status = AcpiPsCompleteOp (WalkState, &Op, AE_OK);
784                     if (ACPI_FAILURE (Status))
785                     {
786                         return_ACPI_STATUS (Status);
787                     }
788                 }
789 
790                 if (Status == AE_CTRL_TERMINATE)
791                 {
792                     Status = AE_OK;
793 
794                     /* Clean up */
795                     do
796                     {
797                         if (Op)
798                         {
799                             Status2 = AcpiPsCompleteThisOp (WalkState, Op);
800                             if (ACPI_FAILURE (Status2))
801                             {
802                                 return_ACPI_STATUS (Status2);
803                             }
804                         }
805 
806                         AcpiPsPopScope (&(WalkState->ParserState), &Op,
807                             &WalkState->ArgTypes, &WalkState->ArgCount);
808 
809                     } while (Op);
810 
811                     return_ACPI_STATUS (Status);
812                 }
813 
814                 else if (ACPI_FAILURE (Status))
815                 {
816                     /* First error is most important */
817 
818                     (void) AcpiPsCompleteThisOp (WalkState, Op);
819                     return_ACPI_STATUS (Status);
820                 }
821             }
822 
823             Status2 = AcpiPsCompleteThisOp (WalkState, Op);
824             if (ACPI_FAILURE (Status2))
825             {
826                 return_ACPI_STATUS (Status2);
827             }
828         }
829 
830         AcpiPsPopScope (&(WalkState->ParserState), &Op, &WalkState->ArgTypes,
831             &WalkState->ArgCount);
832 
833     } while (Op);
834 
835     return_ACPI_STATUS (Status);
836 }
837