xref: /haiku/src/add-ons/kernel/bus_managers/acpi/acpica/components/parser/psloop.c (revision 776c58b2b56d8bcf33638a2ecb6c697f95a1cbf3)
1 /******************************************************************************
2  *
3  * Module Name: psloop - Main AML parse loop
4  *
5  *****************************************************************************/
6 
7 /******************************************************************************
8  *
9  * 1. Copyright Notice
10  *
11  * Some or all of this work - Copyright (c) 1999 - 2012, 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 
117 /*
118  * Parse the AML and build an operation tree as most interpreters, (such as
119  * Perl) do. Parsing is done by hand rather than with a YACC generated parser
120  * to tightly constrain stack and dynamic memory usage. Parsing is kept
121  * flexible and the code fairly compact by parsing based on a list of AML
122  * opcode templates in AmlOpInfo[].
123  */
124 
125 #include "acpi.h"
126 #include "accommon.h"
127 #include "acparser.h"
128 #include "acdispat.h"
129 #include "amlcode.h"
130 
131 #define _COMPONENT          ACPI_PARSER
132         ACPI_MODULE_NAME    ("psloop")
133 
134 static UINT32               AcpiGbl_Depth = 0;
135 
136 
137 /* Local prototypes */
138 
139 static ACPI_STATUS
140 AcpiPsGetAmlOpcode (
141     ACPI_WALK_STATE         *WalkState);
142 
143 static ACPI_STATUS
144 AcpiPsBuildNamedOp (
145     ACPI_WALK_STATE         *WalkState,
146     UINT8                   *AmlOpStart,
147     ACPI_PARSE_OBJECT       *UnnamedOp,
148     ACPI_PARSE_OBJECT       **Op);
149 
150 static ACPI_STATUS
151 AcpiPsCreateOp (
152     ACPI_WALK_STATE         *WalkState,
153     UINT8                   *AmlOpStart,
154     ACPI_PARSE_OBJECT       **NewOp);
155 
156 static ACPI_STATUS
157 AcpiPsGetArguments (
158     ACPI_WALK_STATE         *WalkState,
159     UINT8                   *AmlOpStart,
160     ACPI_PARSE_OBJECT       *Op);
161 
162 static ACPI_STATUS
163 AcpiPsCompleteOp (
164     ACPI_WALK_STATE         *WalkState,
165     ACPI_PARSE_OBJECT       **Op,
166     ACPI_STATUS             Status);
167 
168 static ACPI_STATUS
169 AcpiPsCompleteFinalOp (
170     ACPI_WALK_STATE         *WalkState,
171     ACPI_PARSE_OBJECT       *Op,
172     ACPI_STATUS             Status);
173 
174 static void
175 AcpiPsLinkModuleCode (
176     ACPI_PARSE_OBJECT       *ParentOp,
177     UINT8                   *AmlStart,
178     UINT32                  AmlLength,
179     ACPI_OWNER_ID           OwnerId);
180 
181 
182 /*******************************************************************************
183  *
184  * FUNCTION:    AcpiPsGetAmlOpcode
185  *
186  * PARAMETERS:  WalkState           - Current state
187  *
188  * RETURN:      Status
189  *
190  * DESCRIPTION: Extract the next AML opcode from the input stream.
191  *
192  ******************************************************************************/
193 
194 static ACPI_STATUS
195 AcpiPsGetAmlOpcode (
196     ACPI_WALK_STATE         *WalkState)
197 {
198 
199     ACPI_FUNCTION_TRACE_PTR (PsGetAmlOpcode, WalkState);
200 
201 
202     WalkState->AmlOffset = (UINT32) ACPI_PTR_DIFF (WalkState->ParserState.Aml,
203                                 WalkState->ParserState.AmlStart);
204     WalkState->Opcode = AcpiPsPeekOpcode (&(WalkState->ParserState));
205 
206     /*
207      * First cut to determine what we have found:
208      * 1) A valid AML opcode
209      * 2) A name string
210      * 3) An unknown/invalid opcode
211      */
212     WalkState->OpInfo = AcpiPsGetOpcodeInfo (WalkState->Opcode);
213 
214     switch (WalkState->OpInfo->Class)
215     {
216     case AML_CLASS_ASCII:
217     case AML_CLASS_PREFIX:
218         /*
219          * Starts with a valid prefix or ASCII char, this is a name
220          * string. Convert the bare name string to a namepath.
221          */
222         WalkState->Opcode = AML_INT_NAMEPATH_OP;
223         WalkState->ArgTypes = ARGP_NAMESTRING;
224         break;
225 
226     case AML_CLASS_UNKNOWN:
227 
228         /* The opcode is unrecognized. Complain and skip unknown opcodes */
229 
230         if (WalkState->PassNumber == 2)
231         {
232             ACPI_ERROR ((AE_INFO,
233                 "Unknown opcode 0x%.2X at table offset 0x%.4X, ignoring",
234                 WalkState->Opcode,
235                 (UINT32) (WalkState->AmlOffset + sizeof (ACPI_TABLE_HEADER))));
236 
237             ACPI_DUMP_BUFFER (WalkState->ParserState.Aml - 16, 48);
238 
239 #ifdef ACPI_ASL_COMPILER
240             /*
241              * This is executed for the disassembler only. Output goes
242              * to the disassembled ASL output file.
243              */
244             AcpiOsPrintf (
245                 "/*\nError: Unknown opcode 0x%.2X at table offset 0x%.4X, context:\n",
246                 WalkState->Opcode,
247                 (UINT32) (WalkState->AmlOffset + sizeof (ACPI_TABLE_HEADER)));
248 
249             /* Dump the context surrounding the invalid opcode */
250 
251             AcpiUtDumpBuffer (((UINT8 *) WalkState->ParserState.Aml - 16),
252                 48, DB_BYTE_DISPLAY,
253                 WalkState->AmlOffset + sizeof (ACPI_TABLE_HEADER) - 16);
254             AcpiOsPrintf (" */\n");
255 #endif
256         }
257 
258         /* Increment past one-byte or two-byte opcode */
259 
260         WalkState->ParserState.Aml++;
261         if (WalkState->Opcode > 0xFF) /* Can only happen if first byte is 0x5B */
262         {
263             WalkState->ParserState.Aml++;
264         }
265 
266         return_ACPI_STATUS (AE_CTRL_PARSE_CONTINUE);
267 
268     default:
269 
270         /* Found opcode info, this is a normal opcode */
271 
272         WalkState->ParserState.Aml += AcpiPsGetOpcodeSize (WalkState->Opcode);
273         WalkState->ArgTypes = WalkState->OpInfo->ParseArgs;
274         break;
275     }
276 
277     return_ACPI_STATUS (AE_OK);
278 }
279 
280 
281 /*******************************************************************************
282  *
283  * FUNCTION:    AcpiPsBuildNamedOp
284  *
285  * PARAMETERS:  WalkState           - Current state
286  *              AmlOpStart          - Begin of named Op in AML
287  *              UnnamedOp           - Early Op (not a named Op)
288  *              Op                  - Returned Op
289  *
290  * RETURN:      Status
291  *
292  * DESCRIPTION: Parse a named Op
293  *
294  ******************************************************************************/
295 
296 static ACPI_STATUS
297 AcpiPsBuildNamedOp (
298     ACPI_WALK_STATE         *WalkState,
299     UINT8                   *AmlOpStart,
300     ACPI_PARSE_OBJECT       *UnnamedOp,
301     ACPI_PARSE_OBJECT       **Op)
302 {
303     ACPI_STATUS             Status = AE_OK;
304     ACPI_PARSE_OBJECT       *Arg = NULL;
305 
306 
307     ACPI_FUNCTION_TRACE_PTR (PsBuildNamedOp, WalkState);
308 
309 
310     UnnamedOp->Common.Value.Arg = NULL;
311     UnnamedOp->Common.ArgListLength = 0;
312     UnnamedOp->Common.AmlOpcode = WalkState->Opcode;
313 
314     /*
315      * Get and append arguments until we find the node that contains
316      * the name (the type ARGP_NAME).
317      */
318     while (GET_CURRENT_ARG_TYPE (WalkState->ArgTypes) &&
319           (GET_CURRENT_ARG_TYPE (WalkState->ArgTypes) != ARGP_NAME))
320     {
321         Status = AcpiPsGetNextArg (WalkState, &(WalkState->ParserState),
322                     GET_CURRENT_ARG_TYPE (WalkState->ArgTypes), &Arg);
323         if (ACPI_FAILURE (Status))
324         {
325             return_ACPI_STATUS (Status);
326         }
327 
328         AcpiPsAppendArg (UnnamedOp, Arg);
329         INCREMENT_ARG_LIST (WalkState->ArgTypes);
330     }
331 
332     /*
333      * Make sure that we found a NAME and didn't run out of arguments
334      */
335     if (!GET_CURRENT_ARG_TYPE (WalkState->ArgTypes))
336     {
337         return_ACPI_STATUS (AE_AML_NO_OPERAND);
338     }
339 
340     /* We know that this arg is a name, move to next arg */
341 
342     INCREMENT_ARG_LIST (WalkState->ArgTypes);
343 
344     /*
345      * Find the object. This will either insert the object into
346      * the namespace or simply look it up
347      */
348     WalkState->Op = NULL;
349 
350     Status = WalkState->DescendingCallback (WalkState, Op);
351     if (ACPI_FAILURE (Status))
352     {
353         ACPI_EXCEPTION ((AE_INFO, Status, "During name lookup/catalog"));
354         return_ACPI_STATUS (Status);
355     }
356 
357     if (!*Op)
358     {
359         return_ACPI_STATUS (AE_CTRL_PARSE_CONTINUE);
360     }
361 
362     Status = AcpiPsNextParseState (WalkState, *Op, Status);
363     if (ACPI_FAILURE (Status))
364     {
365         if (Status == AE_CTRL_PENDING)
366         {
367             return_ACPI_STATUS (AE_CTRL_PARSE_PENDING);
368         }
369         return_ACPI_STATUS (Status);
370     }
371 
372     AcpiPsAppendArg (*Op, UnnamedOp->Common.Value.Arg);
373     AcpiGbl_Depth++;
374 
375     if ((*Op)->Common.AmlOpcode == AML_REGION_OP ||
376         (*Op)->Common.AmlOpcode == AML_DATA_REGION_OP)
377     {
378         /*
379          * Defer final parsing of an OperationRegion body, because we don't
380          * have enough info in the first pass to parse it correctly (i.e.,
381          * there may be method calls within the TermArg elements of the body.)
382          *
383          * However, we must continue parsing because the opregion is not a
384          * standalone package -- we don't know where the end is at this point.
385          *
386          * (Length is unknown until parse of the body complete)
387          */
388         (*Op)->Named.Data = AmlOpStart;
389         (*Op)->Named.Length = 0;
390     }
391 
392     return_ACPI_STATUS (AE_OK);
393 }
394 
395 
396 /*******************************************************************************
397  *
398  * FUNCTION:    AcpiPsCreateOp
399  *
400  * PARAMETERS:  WalkState           - Current state
401  *              AmlOpStart          - Op start in AML
402  *              NewOp               - Returned Op
403  *
404  * RETURN:      Status
405  *
406  * DESCRIPTION: Get Op from AML
407  *
408  ******************************************************************************/
409 
410 static ACPI_STATUS
411 AcpiPsCreateOp (
412     ACPI_WALK_STATE         *WalkState,
413     UINT8                   *AmlOpStart,
414     ACPI_PARSE_OBJECT       **NewOp)
415 {
416     ACPI_STATUS             Status = AE_OK;
417     ACPI_PARSE_OBJECT       *Op;
418     ACPI_PARSE_OBJECT       *NamedOp = NULL;
419     ACPI_PARSE_OBJECT       *ParentScope;
420     UINT8                   ArgumentCount;
421     const ACPI_OPCODE_INFO  *OpInfo;
422 
423 
424     ACPI_FUNCTION_TRACE_PTR (PsCreateOp, WalkState);
425 
426 
427     Status = AcpiPsGetAmlOpcode (WalkState);
428     if (Status == AE_CTRL_PARSE_CONTINUE)
429     {
430         return_ACPI_STATUS (AE_CTRL_PARSE_CONTINUE);
431     }
432 
433     /* Create Op structure and append to parent's argument list */
434 
435     WalkState->OpInfo = AcpiPsGetOpcodeInfo (WalkState->Opcode);
436     Op = AcpiPsAllocOp (WalkState->Opcode);
437     if (!Op)
438     {
439         return_ACPI_STATUS (AE_NO_MEMORY);
440     }
441 
442     if (WalkState->OpInfo->Flags & AML_NAMED)
443     {
444         Status = AcpiPsBuildNamedOp (WalkState, AmlOpStart, Op, &NamedOp);
445         AcpiPsFreeOp (Op);
446         if (ACPI_FAILURE (Status))
447         {
448             return_ACPI_STATUS (Status);
449         }
450 
451         *NewOp = NamedOp;
452         return_ACPI_STATUS (AE_OK);
453     }
454 
455     /* Not a named opcode, just allocate Op and append to parent */
456 
457     if (WalkState->OpInfo->Flags & AML_CREATE)
458     {
459         /*
460          * Backup to beginning of CreateXXXfield declaration
461          * BodyLength is unknown until we parse the body
462          */
463         Op->Named.Data = AmlOpStart;
464         Op->Named.Length = 0;
465     }
466 
467     if (WalkState->Opcode == AML_BANK_FIELD_OP)
468     {
469         /*
470          * Backup to beginning of BankField declaration
471          * BodyLength is unknown until we parse the body
472          */
473         Op->Named.Data = AmlOpStart;
474         Op->Named.Length = 0;
475     }
476 
477     ParentScope = AcpiPsGetParentScope (&(WalkState->ParserState));
478     AcpiPsAppendArg (ParentScope, Op);
479 
480     if (ParentScope)
481     {
482         OpInfo = AcpiPsGetOpcodeInfo (ParentScope->Common.AmlOpcode);
483         if (OpInfo->Flags & AML_HAS_TARGET)
484         {
485             ArgumentCount = AcpiPsGetArgumentCount (OpInfo->Type);
486             if (ParentScope->Common.ArgListLength > ArgumentCount)
487             {
488                 Op->Common.Flags |= ACPI_PARSEOP_TARGET;
489             }
490         }
491         else if (ParentScope->Common.AmlOpcode == AML_INCREMENT_OP)
492         {
493             Op->Common.Flags |= ACPI_PARSEOP_TARGET;
494         }
495     }
496 
497     if (WalkState->DescendingCallback != NULL)
498     {
499         /*
500          * Find the object. This will either insert the object into
501          * the namespace or simply look it up
502          */
503         WalkState->Op = *NewOp = Op;
504 
505         Status = WalkState->DescendingCallback (WalkState, &Op);
506         Status = AcpiPsNextParseState (WalkState, Op, Status);
507         if (Status == AE_CTRL_PENDING)
508         {
509             Status = AE_CTRL_PARSE_PENDING;
510         }
511     }
512 
513     return_ACPI_STATUS (Status);
514 }
515 
516 
517 /*******************************************************************************
518  *
519  * FUNCTION:    AcpiPsGetArguments
520  *
521  * PARAMETERS:  WalkState           - Current state
522  *              AmlOpStart          - Op start in AML
523  *              Op                  - Current Op
524  *
525  * RETURN:      Status
526  *
527  * DESCRIPTION: Get arguments for passed Op.
528  *
529  ******************************************************************************/
530 
531 static ACPI_STATUS
532 AcpiPsGetArguments (
533     ACPI_WALK_STATE         *WalkState,
534     UINT8                   *AmlOpStart,
535     ACPI_PARSE_OBJECT       *Op)
536 {
537     ACPI_STATUS             Status = AE_OK;
538     ACPI_PARSE_OBJECT       *Arg = NULL;
539     const ACPI_OPCODE_INFO  *OpInfo;
540 
541 
542     ACPI_FUNCTION_TRACE_PTR (PsGetArguments, WalkState);
543 
544 
545     switch (Op->Common.AmlOpcode)
546     {
547     case AML_BYTE_OP:       /* AML_BYTEDATA_ARG */
548     case AML_WORD_OP:       /* AML_WORDDATA_ARG */
549     case AML_DWORD_OP:      /* AML_DWORDATA_ARG */
550     case AML_QWORD_OP:      /* AML_QWORDATA_ARG */
551     case AML_STRING_OP:     /* AML_ASCIICHARLIST_ARG */
552 
553         /* Fill in constant or string argument directly */
554 
555         AcpiPsGetNextSimpleArg (&(WalkState->ParserState),
556             GET_CURRENT_ARG_TYPE (WalkState->ArgTypes), Op);
557         break;
558 
559     case AML_INT_NAMEPATH_OP:   /* AML_NAMESTRING_ARG */
560 
561         Status = AcpiPsGetNextNamepath (WalkState, &(WalkState->ParserState), Op, 1);
562         if (ACPI_FAILURE (Status))
563         {
564             return_ACPI_STATUS (Status);
565         }
566 
567         WalkState->ArgTypes = 0;
568         break;
569 
570     default:
571         /*
572          * Op is not a constant or string, append each argument to the Op
573          */
574         while (GET_CURRENT_ARG_TYPE (WalkState->ArgTypes) && !WalkState->ArgCount)
575         {
576             WalkState->AmlOffset = (UINT32) ACPI_PTR_DIFF (WalkState->ParserState.Aml,
577                 WalkState->ParserState.AmlStart);
578 
579             Status = AcpiPsGetNextArg (WalkState, &(WalkState->ParserState),
580                         GET_CURRENT_ARG_TYPE (WalkState->ArgTypes), &Arg);
581             if (ACPI_FAILURE (Status))
582             {
583                 return_ACPI_STATUS (Status);
584             }
585 
586             if (Arg)
587             {
588                 Arg->Common.AmlOffset = WalkState->AmlOffset;
589                 AcpiPsAppendArg (Op, Arg);
590             }
591 
592             INCREMENT_ARG_LIST (WalkState->ArgTypes);
593         }
594 
595 
596         /*
597          * Handle executable code at "module-level". This refers to
598          * executable opcodes that appear outside of any control method.
599          */
600         if ((WalkState->PassNumber <= ACPI_IMODE_LOAD_PASS2) &&
601             ((WalkState->ParseFlags & ACPI_PARSE_DISASSEMBLE) == 0))
602         {
603             /*
604              * We want to skip If/Else/While constructs during Pass1 because we
605              * want to actually conditionally execute the code during Pass2.
606              *
607              * Except for disassembly, where we always want to walk the
608              * If/Else/While packages
609              */
610             switch (Op->Common.AmlOpcode)
611             {
612             case AML_IF_OP:
613             case AML_ELSE_OP:
614             case AML_WHILE_OP:
615 
616                 /*
617                  * Currently supported module-level opcodes are:
618                  * IF/ELSE/WHILE. These appear to be the most common,
619                  * and easiest to support since they open an AML
620                  * package.
621                  */
622                 if (WalkState->PassNumber == ACPI_IMODE_LOAD_PASS1)
623                 {
624                     AcpiPsLinkModuleCode (Op->Common.Parent, AmlOpStart,
625                         (UINT32) (WalkState->ParserState.PkgEnd - AmlOpStart),
626                         WalkState->OwnerId);
627                 }
628 
629                 ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
630                     "Pass1: Skipping an If/Else/While body\n"));
631 
632                 /* Skip body of if/else/while in pass 1 */
633 
634                 WalkState->ParserState.Aml = WalkState->ParserState.PkgEnd;
635                 WalkState->ArgCount = 0;
636                 break;
637 
638             default:
639                 /*
640                  * Check for an unsupported executable opcode at module
641                  * level. We must be in PASS1, the parent must be a SCOPE,
642                  * The opcode class must be EXECUTE, and the opcode must
643                  * not be an argument to another opcode.
644                  */
645                 if ((WalkState->PassNumber == ACPI_IMODE_LOAD_PASS1) &&
646                     (Op->Common.Parent->Common.AmlOpcode == AML_SCOPE_OP))
647                 {
648                     OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
649                     if ((OpInfo->Class == AML_CLASS_EXECUTE) &&
650                         (!Arg))
651                     {
652                         ACPI_WARNING ((AE_INFO,
653                             "Unsupported module-level executable opcode "
654                             "0x%.2X at table offset 0x%.4X",
655                             Op->Common.AmlOpcode,
656                             (UINT32) (ACPI_PTR_DIFF (AmlOpStart,
657                                 WalkState->ParserState.AmlStart) +
658                                 sizeof (ACPI_TABLE_HEADER))));
659                     }
660                 }
661                 break;
662             }
663         }
664 
665         /* Special processing for certain opcodes */
666 
667         switch (Op->Common.AmlOpcode)
668         {
669         case AML_METHOD_OP:
670             /*
671              * Skip parsing of control method because we don't have enough
672              * info in the first pass to parse it correctly.
673              *
674              * Save the length and address of the body
675              */
676             Op->Named.Data = WalkState->ParserState.Aml;
677             Op->Named.Length = (UINT32)
678                 (WalkState->ParserState.PkgEnd - WalkState->ParserState.Aml);
679 
680             /* Skip body of method */
681 
682             WalkState->ParserState.Aml = WalkState->ParserState.PkgEnd;
683             WalkState->ArgCount = 0;
684             break;
685 
686         case AML_BUFFER_OP:
687         case AML_PACKAGE_OP:
688         case AML_VAR_PACKAGE_OP:
689 
690             if ((Op->Common.Parent) &&
691                 (Op->Common.Parent->Common.AmlOpcode == AML_NAME_OP) &&
692                 (WalkState->PassNumber <= ACPI_IMODE_LOAD_PASS2))
693             {
694                 /*
695                  * Skip parsing of Buffers and Packages because we don't have
696                  * enough info in the first pass to parse them correctly.
697                  */
698                 Op->Named.Data = AmlOpStart;
699                 Op->Named.Length = (UINT32)
700                     (WalkState->ParserState.PkgEnd - AmlOpStart);
701 
702                 /* Skip body */
703 
704                 WalkState->ParserState.Aml = WalkState->ParserState.PkgEnd;
705                 WalkState->ArgCount = 0;
706             }
707             break;
708 
709         case AML_WHILE_OP:
710 
711             if (WalkState->ControlState)
712             {
713                 WalkState->ControlState->Control.PackageEnd =
714                     WalkState->ParserState.PkgEnd;
715             }
716             break;
717 
718         default:
719 
720             /* No action for all other opcodes */
721             break;
722         }
723 
724         break;
725     }
726 
727     return_ACPI_STATUS (AE_OK);
728 }
729 
730 
731 /*******************************************************************************
732  *
733  * FUNCTION:    AcpiPsLinkModuleCode
734  *
735  * PARAMETERS:  ParentOp            - Parent parser op
736  *              AmlStart            - Pointer to the AML
737  *              AmlLength           - Length of executable AML
738  *              OwnerId             - OwnerId of module level code
739  *
740  * RETURN:      None.
741  *
742  * DESCRIPTION: Wrap the module-level code with a method object and link the
743  *              object to the global list. Note, the mutex field of the method
744  *              object is used to link multiple module-level code objects.
745  *
746  ******************************************************************************/
747 
748 static void
749 AcpiPsLinkModuleCode (
750     ACPI_PARSE_OBJECT       *ParentOp,
751     UINT8                   *AmlStart,
752     UINT32                  AmlLength,
753     ACPI_OWNER_ID           OwnerId)
754 {
755     ACPI_OPERAND_OBJECT     *Prev;
756     ACPI_OPERAND_OBJECT     *Next;
757     ACPI_OPERAND_OBJECT     *MethodObj;
758     ACPI_NAMESPACE_NODE     *ParentNode;
759 
760 
761     /* Get the tail of the list */
762 
763     Prev = Next = AcpiGbl_ModuleCodeList;
764     while (Next)
765     {
766         Prev = Next;
767         Next = Next->Method.Mutex;
768     }
769 
770     /*
771      * Insert the module level code into the list. Merge it if it is
772      * adjacent to the previous element.
773      */
774     if (!Prev ||
775        ((Prev->Method.AmlStart + Prev->Method.AmlLength) != AmlStart))
776     {
777         /* Create, initialize, and link a new temporary method object */
778 
779         MethodObj = AcpiUtCreateInternalObject (ACPI_TYPE_METHOD);
780         if (!MethodObj)
781         {
782             return;
783         }
784 
785         if (ParentOp->Common.Node)
786         {
787             ParentNode = ParentOp->Common.Node;
788         }
789         else
790         {
791             ParentNode = AcpiGbl_RootNode;
792         }
793 
794         MethodObj->Method.AmlStart = AmlStart;
795         MethodObj->Method.AmlLength = AmlLength;
796         MethodObj->Method.OwnerId = OwnerId;
797         MethodObj->Method.InfoFlags |= ACPI_METHOD_MODULE_LEVEL;
798 
799         /*
800          * Save the parent node in NextObject. This is cheating, but we
801          * don't want to expand the method object.
802          */
803         MethodObj->Method.NextObject =
804             ACPI_CAST_PTR (ACPI_OPERAND_OBJECT, ParentNode);
805 
806         if (!Prev)
807         {
808             AcpiGbl_ModuleCodeList = MethodObj;
809         }
810         else
811         {
812             Prev->Method.Mutex = MethodObj;
813         }
814     }
815     else
816     {
817         Prev->Method.AmlLength += AmlLength;
818     }
819 }
820 
821 
822 /*******************************************************************************
823  *
824  * FUNCTION:    AcpiPsCompleteOp
825  *
826  * PARAMETERS:  WalkState           - Current state
827  *              Op                  - Returned Op
828  *              Status              - Parse status before complete Op
829  *
830  * RETURN:      Status
831  *
832  * DESCRIPTION: Complete Op
833  *
834  ******************************************************************************/
835 
836 static ACPI_STATUS
837 AcpiPsCompleteOp (
838     ACPI_WALK_STATE         *WalkState,
839     ACPI_PARSE_OBJECT       **Op,
840     ACPI_STATUS             Status)
841 {
842     ACPI_STATUS             Status2;
843 
844 
845     ACPI_FUNCTION_TRACE_PTR (PsCompleteOp, WalkState);
846 
847 
848     /*
849      * Finished one argument of the containing scope
850      */
851     WalkState->ParserState.Scope->ParseScope.ArgCount--;
852 
853     /* Close this Op (will result in parse subtree deletion) */
854 
855     Status2 = AcpiPsCompleteThisOp (WalkState, *Op);
856     if (ACPI_FAILURE (Status2))
857     {
858         return_ACPI_STATUS (Status2);
859     }
860 
861     *Op = NULL;
862 
863     switch (Status)
864     {
865     case AE_OK:
866         break;
867 
868 
869     case AE_CTRL_TRANSFER:
870 
871         /* We are about to transfer to a called method */
872 
873         WalkState->PrevOp = NULL;
874         WalkState->PrevArgTypes = WalkState->ArgTypes;
875         return_ACPI_STATUS (Status);
876 
877 
878     case AE_CTRL_END:
879 
880         AcpiPsPopScope (&(WalkState->ParserState), Op,
881             &WalkState->ArgTypes, &WalkState->ArgCount);
882 
883         if (*Op)
884         {
885             WalkState->Op = *Op;
886             WalkState->OpInfo = AcpiPsGetOpcodeInfo ((*Op)->Common.AmlOpcode);
887             WalkState->Opcode = (*Op)->Common.AmlOpcode;
888 
889             Status = WalkState->AscendingCallback (WalkState);
890             Status = AcpiPsNextParseState (WalkState, *Op, Status);
891 
892             Status2 = AcpiPsCompleteThisOp (WalkState, *Op);
893             if (ACPI_FAILURE (Status2))
894             {
895                 return_ACPI_STATUS (Status2);
896             }
897         }
898 
899         Status = AE_OK;
900         break;
901 
902 
903     case AE_CTRL_BREAK:
904     case AE_CTRL_CONTINUE:
905 
906         /* Pop off scopes until we find the While */
907 
908         while (!(*Op) || ((*Op)->Common.AmlOpcode != AML_WHILE_OP))
909         {
910             AcpiPsPopScope (&(WalkState->ParserState), Op,
911                 &WalkState->ArgTypes, &WalkState->ArgCount);
912         }
913 
914         /* Close this iteration of the While loop */
915 
916         WalkState->Op = *Op;
917         WalkState->OpInfo = AcpiPsGetOpcodeInfo ((*Op)->Common.AmlOpcode);
918         WalkState->Opcode = (*Op)->Common.AmlOpcode;
919 
920         Status = WalkState->AscendingCallback (WalkState);
921         Status = AcpiPsNextParseState (WalkState, *Op, Status);
922 
923         Status2 = AcpiPsCompleteThisOp (WalkState, *Op);
924         if (ACPI_FAILURE (Status2))
925         {
926             return_ACPI_STATUS (Status2);
927         }
928 
929         Status = AE_OK;
930         break;
931 
932 
933     case AE_CTRL_TERMINATE:
934 
935         /* Clean up */
936         do
937         {
938             if (*Op)
939             {
940                 Status2 = AcpiPsCompleteThisOp (WalkState, *Op);
941                 if (ACPI_FAILURE (Status2))
942                 {
943                     return_ACPI_STATUS (Status2);
944                 }
945 
946                 AcpiUtDeleteGenericState (
947                     AcpiUtPopGenericState (&WalkState->ControlState));
948             }
949 
950             AcpiPsPopScope (&(WalkState->ParserState), Op,
951                 &WalkState->ArgTypes, &WalkState->ArgCount);
952 
953         } while (*Op);
954 
955         return_ACPI_STATUS (AE_OK);
956 
957 
958     default:  /* All other non-AE_OK status */
959 
960         do
961         {
962             if (*Op)
963             {
964                 Status2 = AcpiPsCompleteThisOp (WalkState, *Op);
965                 if (ACPI_FAILURE (Status2))
966                 {
967                     return_ACPI_STATUS (Status2);
968                 }
969             }
970 
971             AcpiPsPopScope (&(WalkState->ParserState), Op,
972                 &WalkState->ArgTypes, &WalkState->ArgCount);
973 
974         } while (*Op);
975 
976 
977 #if 0
978         /*
979          * TBD: Cleanup parse ops on error
980          */
981         if (*Op == NULL)
982         {
983             AcpiPsPopScope (ParserState, Op,
984                 &WalkState->ArgTypes, &WalkState->ArgCount);
985         }
986 #endif
987         WalkState->PrevOp = NULL;
988         WalkState->PrevArgTypes = WalkState->ArgTypes;
989         return_ACPI_STATUS (Status);
990     }
991 
992     /* This scope complete? */
993 
994     if (AcpiPsHasCompletedScope (&(WalkState->ParserState)))
995     {
996         AcpiPsPopScope (&(WalkState->ParserState), Op,
997             &WalkState->ArgTypes, &WalkState->ArgCount);
998         ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Popped scope, Op=%p\n", *Op));
999     }
1000     else
1001     {
1002         *Op = NULL;
1003     }
1004 
1005     return_ACPI_STATUS (AE_OK);
1006 }
1007 
1008 
1009 /*******************************************************************************
1010  *
1011  * FUNCTION:    AcpiPsCompleteFinalOp
1012  *
1013  * PARAMETERS:  WalkState           - Current state
1014  *              Op                  - Current Op
1015  *              Status              - Current parse status before complete last
1016  *                                    Op
1017  *
1018  * RETURN:      Status
1019  *
1020  * DESCRIPTION: Complete last Op.
1021  *
1022  ******************************************************************************/
1023 
1024 static ACPI_STATUS
1025 AcpiPsCompleteFinalOp (
1026     ACPI_WALK_STATE         *WalkState,
1027     ACPI_PARSE_OBJECT       *Op,
1028     ACPI_STATUS             Status)
1029 {
1030     ACPI_STATUS             Status2;
1031 
1032 
1033     ACPI_FUNCTION_TRACE_PTR (PsCompleteFinalOp, WalkState);
1034 
1035 
1036     /*
1037      * Complete the last Op (if not completed), and clear the scope stack.
1038      * It is easily possible to end an AML "package" with an unbounded number
1039      * of open scopes (such as when several ASL blocks are closed with
1040      * sequential closing braces). We want to terminate each one cleanly.
1041      */
1042     ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "AML package complete at Op %p\n", Op));
1043     do
1044     {
1045         if (Op)
1046         {
1047             if (WalkState->AscendingCallback != NULL)
1048             {
1049                 WalkState->Op = Op;
1050                 WalkState->OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
1051                 WalkState->Opcode = Op->Common.AmlOpcode;
1052 
1053                 Status = WalkState->AscendingCallback (WalkState);
1054                 Status = AcpiPsNextParseState (WalkState, Op, Status);
1055                 if (Status == AE_CTRL_PENDING)
1056                 {
1057                     Status = AcpiPsCompleteOp (WalkState, &Op, AE_OK);
1058                     if (ACPI_FAILURE (Status))
1059                     {
1060                         return_ACPI_STATUS (Status);
1061                     }
1062                 }
1063 
1064                 if (Status == AE_CTRL_TERMINATE)
1065                 {
1066                     Status = AE_OK;
1067 
1068                     /* Clean up */
1069                     do
1070                     {
1071                         if (Op)
1072                         {
1073                             Status2 = AcpiPsCompleteThisOp (WalkState, Op);
1074                             if (ACPI_FAILURE (Status2))
1075                             {
1076                                 return_ACPI_STATUS (Status2);
1077                             }
1078                         }
1079 
1080                         AcpiPsPopScope (&(WalkState->ParserState), &Op,
1081                             &WalkState->ArgTypes, &WalkState->ArgCount);
1082 
1083                     } while (Op);
1084 
1085                     return_ACPI_STATUS (Status);
1086                 }
1087 
1088                 else if (ACPI_FAILURE (Status))
1089                 {
1090                     /* First error is most important */
1091 
1092                     (void) AcpiPsCompleteThisOp (WalkState, Op);
1093                     return_ACPI_STATUS (Status);
1094                 }
1095             }
1096 
1097             Status2 = AcpiPsCompleteThisOp (WalkState, Op);
1098             if (ACPI_FAILURE (Status2))
1099             {
1100                 return_ACPI_STATUS (Status2);
1101             }
1102         }
1103 
1104         AcpiPsPopScope (&(WalkState->ParserState), &Op, &WalkState->ArgTypes,
1105             &WalkState->ArgCount);
1106 
1107     } while (Op);
1108 
1109     return_ACPI_STATUS (Status);
1110 }
1111 
1112 
1113 /*******************************************************************************
1114  *
1115  * FUNCTION:    AcpiPsParseLoop
1116  *
1117  * PARAMETERS:  WalkState           - Current state
1118  *
1119  * RETURN:      Status
1120  *
1121  * DESCRIPTION: Parse AML (pointed to by the current parser state) and return
1122  *              a tree of ops.
1123  *
1124  ******************************************************************************/
1125 
1126 ACPI_STATUS
1127 AcpiPsParseLoop (
1128     ACPI_WALK_STATE         *WalkState)
1129 {
1130     ACPI_STATUS             Status = AE_OK;
1131     ACPI_PARSE_OBJECT       *Op = NULL;     /* current op */
1132     ACPI_PARSE_STATE        *ParserState;
1133     UINT8                   *AmlOpStart = NULL;
1134 
1135 
1136     ACPI_FUNCTION_TRACE_PTR (PsParseLoop, WalkState);
1137 
1138 
1139     if (WalkState->DescendingCallback == NULL)
1140     {
1141         return_ACPI_STATUS (AE_BAD_PARAMETER);
1142     }
1143 
1144     ParserState = &WalkState->ParserState;
1145     WalkState->ArgTypes = 0;
1146 
1147 #if (!defined (ACPI_NO_METHOD_EXECUTION) && !defined (ACPI_CONSTANT_EVAL_ONLY))
1148 
1149     if (WalkState->WalkType & ACPI_WALK_METHOD_RESTART)
1150     {
1151         /* We are restarting a preempted control method */
1152 
1153         if (AcpiPsHasCompletedScope (ParserState))
1154         {
1155             /*
1156              * We must check if a predicate to an IF or WHILE statement
1157              * was just completed
1158              */
1159             if ((ParserState->Scope->ParseScope.Op) &&
1160                ((ParserState->Scope->ParseScope.Op->Common.AmlOpcode == AML_IF_OP) ||
1161                 (ParserState->Scope->ParseScope.Op->Common.AmlOpcode == AML_WHILE_OP)) &&
1162                 (WalkState->ControlState) &&
1163                 (WalkState->ControlState->Common.State ==
1164                     ACPI_CONTROL_PREDICATE_EXECUTING))
1165             {
1166                 /*
1167                  * A predicate was just completed, get the value of the
1168                  * predicate and branch based on that value
1169                  */
1170                 WalkState->Op = NULL;
1171                 Status = AcpiDsGetPredicateValue (WalkState, ACPI_TO_POINTER (TRUE));
1172                 if (ACPI_FAILURE (Status) &&
1173                     ((Status & AE_CODE_MASK) != AE_CODE_CONTROL))
1174                 {
1175                     if (Status == AE_AML_NO_RETURN_VALUE)
1176                     {
1177                         ACPI_EXCEPTION ((AE_INFO, Status,
1178                             "Invoked method did not return a value"));
1179                     }
1180 
1181                     ACPI_EXCEPTION ((AE_INFO, Status, "GetPredicate Failed"));
1182                     return_ACPI_STATUS (Status);
1183                 }
1184 
1185                 Status = AcpiPsNextParseState (WalkState, Op, Status);
1186             }
1187 
1188             AcpiPsPopScope (ParserState, &Op,
1189                 &WalkState->ArgTypes, &WalkState->ArgCount);
1190             ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Popped scope, Op=%p\n", Op));
1191         }
1192         else if (WalkState->PrevOp)
1193         {
1194             /* We were in the middle of an op */
1195 
1196             Op = WalkState->PrevOp;
1197             WalkState->ArgTypes = WalkState->PrevArgTypes;
1198         }
1199     }
1200 #endif
1201 
1202     /* Iterative parsing loop, while there is more AML to process: */
1203 
1204     while ((ParserState->Aml < ParserState->AmlEnd) || (Op))
1205     {
1206         AmlOpStart = ParserState->Aml;
1207         if (!Op)
1208         {
1209             Status = AcpiPsCreateOp (WalkState, AmlOpStart, &Op);
1210             if (ACPI_FAILURE (Status))
1211             {
1212                 if (Status == AE_CTRL_PARSE_CONTINUE)
1213                 {
1214                     continue;
1215                 }
1216 
1217                 if (Status == AE_CTRL_PARSE_PENDING)
1218                 {
1219                     Status = AE_OK;
1220                 }
1221 
1222                 Status = AcpiPsCompleteOp (WalkState, &Op, Status);
1223                 if (ACPI_FAILURE (Status))
1224                 {
1225                     return_ACPI_STATUS (Status);
1226                 }
1227 
1228                 continue;
1229             }
1230 
1231             Op->Common.AmlOffset = WalkState->AmlOffset;
1232 
1233             if (WalkState->OpInfo)
1234             {
1235                 ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
1236                     "Opcode %4.4X [%s] Op %p Aml %p AmlOffset %5.5X\n",
1237                      (UINT32) Op->Common.AmlOpcode, WalkState->OpInfo->Name,
1238                      Op, ParserState->Aml, Op->Common.AmlOffset));
1239             }
1240         }
1241 
1242 
1243         /*
1244          * Start ArgCount at zero because we don't know if there are
1245          * any args yet
1246          */
1247         WalkState->ArgCount  = 0;
1248 
1249         /* Are there any arguments that must be processed? */
1250 
1251         if (WalkState->ArgTypes)
1252         {
1253             /* Get arguments */
1254 
1255             Status = AcpiPsGetArguments (WalkState, AmlOpStart, Op);
1256             if (ACPI_FAILURE (Status))
1257             {
1258                 Status = AcpiPsCompleteOp (WalkState, &Op, Status);
1259                 if (ACPI_FAILURE (Status))
1260                 {
1261                     return_ACPI_STATUS (Status);
1262                 }
1263 
1264                 continue;
1265             }
1266         }
1267 
1268         /* Check for arguments that need to be processed */
1269 
1270         if (WalkState->ArgCount)
1271         {
1272             /*
1273              * There are arguments (complex ones), push Op and
1274              * prepare for argument
1275              */
1276             Status = AcpiPsPushScope (ParserState, Op,
1277                         WalkState->ArgTypes, WalkState->ArgCount);
1278             if (ACPI_FAILURE (Status))
1279             {
1280                 Status = AcpiPsCompleteOp (WalkState, &Op, Status);
1281                 if (ACPI_FAILURE (Status))
1282                 {
1283                     return_ACPI_STATUS (Status);
1284                 }
1285 
1286                 continue;
1287             }
1288 
1289             Op = NULL;
1290             continue;
1291         }
1292 
1293         /*
1294          * All arguments have been processed -- Op is complete,
1295          * prepare for next
1296          */
1297         WalkState->OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
1298         if (WalkState->OpInfo->Flags & AML_NAMED)
1299         {
1300             if (AcpiGbl_Depth)
1301             {
1302                 AcpiGbl_Depth--;
1303             }
1304 
1305             if (Op->Common.AmlOpcode == AML_REGION_OP ||
1306                 Op->Common.AmlOpcode == AML_DATA_REGION_OP)
1307             {
1308                 /*
1309                  * Skip parsing of control method or opregion body,
1310                  * because we don't have enough info in the first pass
1311                  * to parse them correctly.
1312                  *
1313                  * Completed parsing an OpRegion declaration, we now
1314                  * know the length.
1315                  */
1316                 Op->Named.Length = (UINT32) (ParserState->Aml - Op->Named.Data);
1317             }
1318         }
1319 
1320         if (WalkState->OpInfo->Flags & AML_CREATE)
1321         {
1322             /*
1323              * Backup to beginning of CreateXXXfield declaration (1 for
1324              * Opcode)
1325              *
1326              * BodyLength is unknown until we parse the body
1327              */
1328             Op->Named.Length = (UINT32) (ParserState->Aml - Op->Named.Data);
1329         }
1330 
1331         if (Op->Common.AmlOpcode == AML_BANK_FIELD_OP)
1332         {
1333             /*
1334              * Backup to beginning of BankField declaration
1335              *
1336              * BodyLength is unknown until we parse the body
1337              */
1338             Op->Named.Length = (UINT32) (ParserState->Aml - Op->Named.Data);
1339         }
1340 
1341         /* This op complete, notify the dispatcher */
1342 
1343         if (WalkState->AscendingCallback != NULL)
1344         {
1345             WalkState->Op = Op;
1346             WalkState->Opcode = Op->Common.AmlOpcode;
1347 
1348             Status = WalkState->AscendingCallback (WalkState);
1349             Status = AcpiPsNextParseState (WalkState, Op, Status);
1350             if (Status == AE_CTRL_PENDING)
1351             {
1352                 Status = AE_OK;
1353             }
1354         }
1355 
1356         Status = AcpiPsCompleteOp (WalkState, &Op, Status);
1357         if (ACPI_FAILURE (Status))
1358         {
1359             return_ACPI_STATUS (Status);
1360         }
1361 
1362     } /* while ParserState->Aml */
1363 
1364     Status = AcpiPsCompleteFinalOp (WalkState, Op, Status);
1365     return_ACPI_STATUS (Status);
1366 }
1367