aslfold.c revision 281687
1/******************************************************************************
2 *
3 * Module Name: aslfold - Constant folding
4 *
5 *****************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2015, Intel Corp.
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 *    notice, this list of conditions, and the following disclaimer,
16 *    without modification.
17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18 *    substantially similar to the "NO WARRANTY" disclaimer below
19 *    ("Disclaimer") and any redistribution must be conditioned upon
20 *    including a substantially similar Disclaimer requirement for further
21 *    binary redistribution.
22 * 3. Neither the names of the above-listed copyright holders nor the names
23 *    of any contributors may be used to endorse or promote products derived
24 *    from this software without specific prior written permission.
25 *
26 * Alternatively, this software may be distributed under the terms of the
27 * GNU General Public License ("GPL") version 2 as published by the Free
28 * Software Foundation.
29 *
30 * NO WARRANTY
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41 * POSSIBILITY OF SUCH DAMAGES.
42 */
43
44#include <contrib/dev/acpica/compiler/aslcompiler.h>
45#include "aslcompiler.y.h"
46#include <contrib/dev/acpica/include/amlcode.h>
47
48#include <contrib/dev/acpica/include/acdispat.h>
49#include <contrib/dev/acpica/include/acparser.h>
50
51#define _COMPONENT          ACPI_COMPILER
52        ACPI_MODULE_NAME    ("aslfold")
53
54/* Local prototypes */
55
56static ACPI_STATUS
57OpcAmlEvaluationWalk1 (
58    ACPI_PARSE_OBJECT       *Op,
59    UINT32                  Level,
60    void                    *Context);
61
62static ACPI_STATUS
63OpcAmlEvaluationWalk2 (
64    ACPI_PARSE_OBJECT       *Op,
65    UINT32                  Level,
66    void                    *Context);
67
68static ACPI_STATUS
69OpcAmlCheckForConstant (
70    ACPI_PARSE_OBJECT       *Op,
71    UINT32                  Level,
72    void                    *Context);
73
74static void
75OpcUpdateIntegerNode (
76    ACPI_PARSE_OBJECT       *Op,
77    UINT64                  Value);
78
79static ACPI_STATUS
80TrTransformToStoreOp (
81    ACPI_PARSE_OBJECT       *Op,
82    ACPI_WALK_STATE         *WalkState);
83
84static ACPI_STATUS
85TrSimpleConstantReduction (
86    ACPI_PARSE_OBJECT       *Op,
87    ACPI_WALK_STATE         *WalkState);
88
89static void
90TrInstallReducedConstant (
91    ACPI_PARSE_OBJECT       *Op,
92    ACPI_OPERAND_OBJECT     *ObjDesc);
93
94
95/*******************************************************************************
96 *
97 * FUNCTION:    OpcAmlConstantWalk
98 *
99 * PARAMETERS:  ASL_WALK_CALLBACK
100 *
101 * RETURN:      Status
102 *
103 * DESCRIPTION: Reduce an Op and its subtree to a constant if possible
104 *
105 ******************************************************************************/
106
107ACPI_STATUS
108OpcAmlConstantWalk (
109    ACPI_PARSE_OBJECT       *Op,
110    UINT32                  Level,
111    void                    *Context)
112{
113    ACPI_WALK_STATE         *WalkState;
114    ACPI_STATUS             Status = AE_OK;
115
116
117    if (Op->Asl.CompileFlags == 0)
118    {
119        return (AE_OK);
120    }
121
122    /*
123     * Only interested in subtrees that could possibly contain
124     * expressions that can be evaluated at this time
125     */
126    if ((!(Op->Asl.CompileFlags & NODE_COMPILE_TIME_CONST)) ||
127          (Op->Asl.CompileFlags & NODE_IS_TARGET))
128    {
129        return (AE_OK);
130    }
131
132    /* Create a new walk state */
133
134    WalkState = AcpiDsCreateWalkState (0, NULL, NULL, NULL);
135    if (!WalkState)
136    {
137        return (AE_NO_MEMORY);
138    }
139
140    WalkState->NextOp = NULL;
141    WalkState->Params = NULL;
142
143    /*
144     * Examine the entire subtree -- all nodes must be constants
145     * or type 3/4/5 opcodes
146     */
147    Status = TrWalkParseTree (Op, ASL_WALK_VISIT_DOWNWARD,
148        OpcAmlCheckForConstant, NULL, WalkState);
149
150    /*
151     * Did we find an entire subtree that contains all constants
152     * and type 3/4/5 opcodes?
153     */
154    switch (Status)
155    {
156    case AE_OK:
157
158        /* Simple case, like Add(3,4) -> 7 */
159
160        Status = TrSimpleConstantReduction (Op, WalkState);
161        break;
162
163    case AE_CTRL_RETURN_VALUE:
164
165        /* More complex case, like Add(3,4,Local0) -> Store(7,Local0) */
166
167        Status = TrTransformToStoreOp (Op, WalkState);
168        break;
169
170    case AE_TYPE:
171
172        AcpiDsDeleteWalkState (WalkState);
173        return (AE_OK);
174
175    default:
176        AcpiDsDeleteWalkState (WalkState);
177        break;
178    }
179
180    if (ACPI_FAILURE (Status))
181    {
182        DbgPrint (ASL_PARSE_OUTPUT, "Cannot resolve, %s\n",
183            AcpiFormatException (Status));
184
185        /* We could not resolve the subtree for some reason */
186
187        AslError (ASL_ERROR, ASL_MSG_CONSTANT_EVALUATION, Op,
188            (char *) AcpiFormatException (Status));
189
190        /* Set the subtree value to ZERO anyway. Eliminates further errors */
191
192        OpcUpdateIntegerNode (Op, 0);
193    }
194
195    /* Abort the walk of this subtree, we are done with it */
196
197    return (AE_CTRL_DEPTH);
198}
199
200
201/*******************************************************************************
202 *
203 * FUNCTION:    OpcAmlCheckForConstant
204 *
205 * PARAMETERS:  ASL_WALK_CALLBACK
206 *
207 * RETURN:      Status
208 *
209 * DESCRIPTION: Check one Op for a type 3/4/5 AML opcode
210 *
211 ******************************************************************************/
212
213static ACPI_STATUS
214OpcAmlCheckForConstant (
215    ACPI_PARSE_OBJECT       *Op,
216    UINT32                  Level,
217    void                    *Context)
218{
219    ACPI_WALK_STATE         *WalkState = Context;
220    ACPI_STATUS             Status = AE_OK;
221
222
223    WalkState->Op = Op;
224    WalkState->Opcode = Op->Common.AmlOpcode;
225    WalkState->OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
226
227    DbgPrint (ASL_PARSE_OUTPUT, "[%.4d] Opcode: %12.12s ",
228        Op->Asl.LogicalLineNumber, Op->Asl.ParseOpName);
229
230    /*
231     * TBD: Ignore buffer constants for now. The problem is that these
232     * constants have been transformed into RAW_DATA at this point, from
233     * the parse tree transform process which currently happens before
234     * the constant folding process. We may need to defer this transform
235     * for buffer until after the constant folding.
236     */
237    if (WalkState->Opcode == AML_BUFFER_OP)
238    {
239        Status = AE_TYPE;
240        goto CleanupAndExit;
241    }
242
243    /*
244     * These opcodes do not appear in the OpcodeInfo table, but
245     * they represent constants, so abort the constant walk now.
246     */
247    if ((WalkState->Opcode == AML_RAW_DATA_BYTE) ||
248        (WalkState->Opcode == AML_RAW_DATA_WORD) ||
249        (WalkState->Opcode == AML_RAW_DATA_DWORD) ||
250        (WalkState->Opcode == AML_RAW_DATA_QWORD))
251    {
252        DbgPrint (ASL_PARSE_OUTPUT, "RAW DATA");
253        Status = AE_TYPE;
254        goto CleanupAndExit;
255    }
256
257    /* Type 3/4/5 opcodes have the AML_CONSTANT flag set */
258
259    if (!(WalkState->OpInfo->Flags & AML_CONSTANT))
260    {
261        /* Not 3/4/5 opcode, but maybe can convert to STORE */
262
263        if (Op->Asl.CompileFlags & NODE_IS_TARGET)
264        {
265            DbgPrint (ASL_PARSE_OUTPUT,
266                "**** Valid Target, transform to Store ****\n");
267            return (AE_CTRL_RETURN_VALUE);
268        }
269
270        /* Expression cannot be reduced */
271
272        DbgPrint (ASL_PARSE_OUTPUT,
273            "**** Not a Type 3/4/5 opcode (%s) ****",
274             Op->Asl.ParseOpName);
275
276        Status = AE_TYPE;
277        goto CleanupAndExit;
278    }
279
280    /* Debug output */
281
282    DbgPrint (ASL_PARSE_OUTPUT, "TYPE_345");
283
284    if (Op->Asl.CompileFlags & NODE_IS_TARGET)
285    {
286        if (Op->Asl.ParseOpcode == PARSEOP_ZERO)
287        {
288            DbgPrint (ASL_PARSE_OUTPUT, "%-16s", " NULL TARGET");
289        }
290        else
291        {
292            DbgPrint (ASL_PARSE_OUTPUT, "%-16s", " VALID TARGET");
293        }
294    }
295    if (Op->Asl.CompileFlags & NODE_IS_TERM_ARG)
296    {
297        DbgPrint (ASL_PARSE_OUTPUT, "%-16s", " TERMARG");
298    }
299
300CleanupAndExit:
301
302    /* Dump the node compile flags also */
303
304    TrPrintNodeCompileFlags (Op->Asl.CompileFlags);
305    DbgPrint (ASL_PARSE_OUTPUT, "\n");
306    return (Status);
307}
308
309
310/*******************************************************************************
311 *
312 * FUNCTION:    TrSimpleConstantReduction
313 *
314 * PARAMETERS:  Op                  - Parent operator to be transformed
315 *              WalkState           - Current walk state
316 *
317 * RETURN:      Status
318 *
319 * DESCRIPTION: Reduce an entire AML operation to a single constant. The
320 *              operation must not have a target operand.
321 *
322 *              Add (32,64) --> 96
323 *
324 ******************************************************************************/
325
326static ACPI_STATUS
327TrSimpleConstantReduction (
328    ACPI_PARSE_OBJECT       *Op,
329    ACPI_WALK_STATE         *WalkState)
330{
331    ACPI_PARSE_OBJECT       *RootOp;
332    ACPI_PARSE_OBJECT       *OriginalParentOp;
333    ACPI_OPERAND_OBJECT     *ObjDesc;
334    ACPI_STATUS             Status;
335
336
337    DbgPrint (ASL_PARSE_OUTPUT,
338        "Simple subtree constant reduction, operator to constant\n");
339
340    /* Allocate a new temporary root for this subtree */
341
342    RootOp = TrAllocateNode (PARSEOP_INTEGER);
343    if (!RootOp)
344    {
345        return (AE_NO_MEMORY);
346    }
347
348    RootOp->Common.AmlOpcode = AML_INT_EVAL_SUBTREE_OP;
349
350    OriginalParentOp = Op->Common.Parent;
351    Op->Common.Parent = RootOp;
352
353    /* Hand off the subtree to the AML interpreter */
354
355    WalkState->CallerReturnDesc = &ObjDesc;
356
357    Status = TrWalkParseTree (Op, ASL_WALK_VISIT_TWICE,
358        OpcAmlEvaluationWalk1, OpcAmlEvaluationWalk2, WalkState);
359
360    /* Restore original parse tree */
361
362    Op->Common.Parent = OriginalParentOp;
363
364    if (ACPI_FAILURE (Status))
365    {
366        DbgPrint (ASL_PARSE_OUTPUT,
367            "Constant Subtree evaluation(1), %s\n",
368            AcpiFormatException (Status));
369        return (Status);
370    }
371
372    /* Get the final result */
373
374    Status = AcpiDsResultPop (&ObjDesc, WalkState);
375    if (ACPI_FAILURE (Status))
376    {
377        DbgPrint (ASL_PARSE_OUTPUT,
378            "Constant Subtree evaluation(2), %s\n",
379            AcpiFormatException (Status));
380        return (Status);
381    }
382
383    TrInstallReducedConstant (Op, ObjDesc);
384
385    UtSetParseOpName (Op);
386    Op->Asl.Child = NULL;
387    return (AE_OK);
388}
389
390
391/*******************************************************************************
392 *
393 * FUNCTION:    TrTransformToStoreOp
394 *
395 * PARAMETERS:  Op                  - Parent operator to be transformed
396 *              WalkState           - Current walk state
397 *
398 * RETURN:      Status
399 *
400 * DESCRIPTION: Transforms a single AML operation with a constant and target
401 *              to a simple store operation:
402 *
403 *              Add (32,64,DATA) --> Store (96,DATA)
404 *
405 ******************************************************************************/
406
407static ACPI_STATUS
408TrTransformToStoreOp (
409    ACPI_PARSE_OBJECT       *Op,
410    ACPI_WALK_STATE         *WalkState)
411{
412    ACPI_PARSE_OBJECT       *OriginalTarget;
413    ACPI_PARSE_OBJECT       *NewTarget;
414    ACPI_PARSE_OBJECT       *Child1;
415    ACPI_PARSE_OBJECT       *Child2;
416    ACPI_OPERAND_OBJECT     *ObjDesc;
417    ACPI_PARSE_OBJECT       *NewParent;
418    ACPI_PARSE_OBJECT       *OriginalParent;
419    ACPI_STATUS             Status;
420
421
422    DbgPrint (ASL_PARSE_OUTPUT,
423        "Reduction/Transform to StoreOp: Store(Constant, Target)\n");
424
425    /* Extract the operands */
426
427    Child1 = Op->Asl.Child;
428    Child2 = Child1->Asl.Next;
429
430    /*
431     * Special case for DIVIDE -- it has two targets. The first
432     * is for the remainder and if present, we will not attempt
433     * to reduce the expression.
434     */
435    if (Op->Asl.ParseOpcode == PARSEOP_DIVIDE)
436    {
437        Child2 = Child2->Asl.Next;
438        if (Child2->Asl.ParseOpcode != PARSEOP_ZERO)
439        {
440            DbgPrint (ASL_PARSE_OUTPUT,
441                "Cannot reduce DIVIDE - has two targets\n\n");
442            return (AE_OK);
443        }
444    }
445
446    /*
447     * Create a NULL (zero) target so that we can use the
448     * interpreter to evaluate the expression.
449     */
450    NewTarget = TrCreateNullTarget ();
451    NewTarget->Common.AmlOpcode = AML_INT_NAMEPATH_OP;
452
453    /* Handle one-operand cases (NOT, TOBCD, etc.) */
454
455    if (!Child2->Asl.Next)
456    {
457        Child2 = Child1;
458    }
459
460    /* Link in new NULL target as the last operand */
461
462    OriginalTarget = Child2->Asl.Next;
463    Child2->Asl.Next = NewTarget;
464    NewTarget->Asl.Parent = OriginalTarget->Asl.Parent;
465
466    NewParent = TrAllocateNode (PARSEOP_INTEGER);
467    NewParent->Common.AmlOpcode = AML_INT_EVAL_SUBTREE_OP;
468
469    OriginalParent = Op->Common.Parent;
470    Op->Common.Parent = NewParent;
471
472    /* Hand off the subtree to the AML interpreter */
473
474    WalkState->CallerReturnDesc = &ObjDesc;
475
476    Status = TrWalkParseTree (Op, ASL_WALK_VISIT_TWICE,
477        OpcAmlEvaluationWalk1, OpcAmlEvaluationWalk2, WalkState);
478    if (ACPI_FAILURE (Status))
479    {
480        DbgPrint (ASL_PARSE_OUTPUT,
481            "Constant Subtree evaluation(3), %s\n",
482            AcpiFormatException (Status));
483        goto EvalError;
484    }
485
486    /* Get the final result */
487
488    Status = AcpiDsResultPop (&ObjDesc, WalkState);
489    if (ACPI_FAILURE (Status))
490    {
491        DbgPrint (ASL_PARSE_OUTPUT,
492            "Constant Subtree evaluation(4), %s\n",
493            AcpiFormatException (Status));
494        goto EvalError;
495    }
496
497    /* Folded constant is in ObjDesc, store into Child1 */
498
499    TrInstallReducedConstant (Child1, ObjDesc);
500
501    /* Convert operator to STORE */
502
503    Op->Asl.ParseOpcode = PARSEOP_STORE;
504    Op->Asl.AmlOpcode = AML_STORE_OP;
505    UtSetParseOpName (Op);
506    Op->Common.Parent = OriginalParent;
507
508    /* Truncate any subtree expressions, they have been evaluated */
509
510    Child1->Asl.Child = NULL;
511    Child2->Asl.Child = NULL;
512
513    /* First child is the folded constant */
514
515    /* Second child will be the target */
516
517    Child1->Asl.Next = OriginalTarget;
518    return (AE_OK);
519
520
521EvalError:
522
523    /* Restore original links */
524
525    Op->Common.Parent = OriginalParent;
526    Child2->Asl.Next = OriginalTarget;
527    return (Status);
528}
529
530
531/*******************************************************************************
532 *
533 * FUNCTION:    TrInstallReducedConstant
534 *
535 * PARAMETERS:  Op                  - Parent operator to be transformed
536 *              ObjDesc             - Reduced constant to be installed
537 *
538 * RETURN:      None
539 *
540 * DESCRIPTION: Transform the original operator to a simple constant.
541 *              Handles Integers, Strings, and Buffers.
542 *
543 ******************************************************************************/
544
545static void
546TrInstallReducedConstant (
547    ACPI_PARSE_OBJECT       *Op,
548    ACPI_OPERAND_OBJECT     *ObjDesc)
549{
550    ACPI_PARSE_OBJECT       *RootOp;
551
552
553    TotalFolds++;
554    AslError (ASL_OPTIMIZATION, ASL_MSG_CONSTANT_FOLDED, Op,
555        Op->Asl.ParseOpName);
556
557    /*
558     * Because we know we executed type 3/4/5 opcodes above, we know that
559     * the result must be either an Integer, String, or Buffer.
560     */
561    switch (ObjDesc->Common.Type)
562    {
563    case ACPI_TYPE_INTEGER:
564
565        OpcUpdateIntegerNode (Op, ObjDesc->Integer.Value);
566
567        DbgPrint (ASL_PARSE_OUTPUT,
568            "Constant expression reduced to (%s) %8.8X%8.8X\n\n",
569            Op->Asl.ParseOpName,
570            ACPI_FORMAT_UINT64 (Op->Common.Value.Integer));
571        break;
572
573    case ACPI_TYPE_STRING:
574
575        Op->Asl.ParseOpcode = PARSEOP_STRING_LITERAL;
576        Op->Common.AmlOpcode = AML_STRING_OP;
577        Op->Asl.AmlLength = ACPI_STRLEN (ObjDesc->String.Pointer) + 1;
578        Op->Common.Value.String = ObjDesc->String.Pointer;
579
580        DbgPrint (ASL_PARSE_OUTPUT,
581            "Constant expression reduced to (STRING) %s\n\n",
582            Op->Common.Value.String);
583
584        break;
585
586    case ACPI_TYPE_BUFFER:
587
588        Op->Asl.ParseOpcode = PARSEOP_BUFFER;
589        Op->Common.AmlOpcode = AML_BUFFER_OP;
590        Op->Asl.CompileFlags = NODE_AML_PACKAGE;
591        UtSetParseOpName (Op);
592
593        /* Child node is the buffer length */
594
595        RootOp = TrAllocateNode (PARSEOP_INTEGER);
596
597        RootOp->Asl.AmlOpcode = AML_DWORD_OP;
598        RootOp->Asl.Value.Integer = ObjDesc->Buffer.Length;
599        RootOp->Asl.Parent = Op;
600
601        (void) OpcSetOptimalIntegerSize (RootOp);
602
603        Op->Asl.Child = RootOp;
604        Op = RootOp;
605        UtSetParseOpName (Op);
606
607        /* Peer to the child is the raw buffer data */
608
609        RootOp = TrAllocateNode (PARSEOP_RAW_DATA);
610        RootOp->Asl.AmlOpcode = AML_RAW_DATA_BUFFER;
611        RootOp->Asl.AmlLength = ObjDesc->Buffer.Length;
612        RootOp->Asl.Value.String = (char *) ObjDesc->Buffer.Pointer;
613        RootOp->Asl.Parent = Op->Asl.Parent;
614
615        Op->Asl.Next = RootOp;
616        Op = RootOp;
617
618        DbgPrint (ASL_PARSE_OUTPUT,
619            "Constant expression reduced to (BUFFER) length %X\n\n",
620            ObjDesc->Buffer.Length);
621        break;
622
623    default:
624        break;
625    }
626}
627
628
629/*******************************************************************************
630 *
631 * FUNCTION:    OpcUpdateIntegerNode
632 *
633 * PARAMETERS:  Op                  - Current parse object
634 *              Value               - Value for the integer op
635 *
636 * RETURN:      None
637 *
638 * DESCRIPTION: Update node to the correct Integer type and value
639 *
640 ******************************************************************************/
641
642static void
643OpcUpdateIntegerNode (
644    ACPI_PARSE_OBJECT       *Op,
645    UINT64                  Value)
646{
647
648    Op->Common.Value.Integer = Value;
649
650    /*
651     * The AmlLength is used by the parser to indicate a constant,
652     * (if non-zero). Length is either (1/2/4/8)
653     */
654    switch (Op->Asl.AmlLength)
655    {
656    case 1:
657
658        TrUpdateNode (PARSEOP_BYTECONST, Op);
659        Op->Asl.AmlOpcode = AML_RAW_DATA_BYTE;
660        break;
661
662    case 2:
663
664        TrUpdateNode (PARSEOP_WORDCONST, Op);
665        Op->Asl.AmlOpcode = AML_RAW_DATA_WORD;
666        break;
667
668    case 4:
669
670        TrUpdateNode (PARSEOP_DWORDCONST, Op);
671        Op->Asl.AmlOpcode = AML_RAW_DATA_DWORD;
672        break;
673
674    case 8:
675
676        TrUpdateNode (PARSEOP_QWORDCONST, Op);
677        Op->Asl.AmlOpcode = AML_RAW_DATA_QWORD;
678        break;
679
680    case 0:
681    default:
682
683        OpcSetOptimalIntegerSize (Op);
684        TrUpdateNode (PARSEOP_INTEGER, Op);
685        break;
686    }
687
688    Op->Asl.AmlLength = 0;
689}
690
691
692/*******************************************************************************
693 *
694 * FUNCTION:    OpcAmlEvaluationWalk1
695 *
696 * PARAMETERS:  ASL_WALK_CALLBACK
697 *
698 * RETURN:      Status
699 *
700 * DESCRIPTION: Descending callback for AML execution of constant subtrees
701 *
702 ******************************************************************************/
703
704static ACPI_STATUS
705OpcAmlEvaluationWalk1 (
706    ACPI_PARSE_OBJECT       *Op,
707    UINT32                  Level,
708    void                    *Context)
709{
710    ACPI_WALK_STATE         *WalkState = Context;
711    ACPI_STATUS             Status;
712    ACPI_PARSE_OBJECT       *OutOp;
713
714
715    WalkState->Op = Op;
716    WalkState->Opcode = Op->Common.AmlOpcode;
717    WalkState->OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
718
719    /* Copy child pointer to Arg for compatibility with Interpreter */
720
721    if (Op->Asl.Child)
722    {
723        Op->Common.Value.Arg = Op->Asl.Child;
724    }
725
726    /* Call AML dispatcher */
727
728    Status = AcpiDsExecBeginOp (WalkState, &OutOp);
729    if (ACPI_FAILURE (Status))
730    {
731        DbgPrint (ASL_PARSE_OUTPUT,
732            "%s Constant interpretation failed (1) - %s\n",
733            Op->Asl.ParseOpName, AcpiFormatException (Status));
734    }
735
736    return (Status);
737}
738
739
740/*******************************************************************************
741 *
742 * FUNCTION:    OpcAmlEvaluationWalk2
743 *
744 * PARAMETERS:  ASL_WALK_CALLBACK
745 *
746 * RETURN:      Status
747 *
748 * DESCRIPTION: Ascending callback for AML execution of constant subtrees
749 *
750 ******************************************************************************/
751
752static ACPI_STATUS
753OpcAmlEvaluationWalk2 (
754    ACPI_PARSE_OBJECT       *Op,
755    UINT32                  Level,
756    void                    *Context)
757{
758    ACPI_WALK_STATE         *WalkState = Context;
759    ACPI_STATUS             Status;
760
761
762    WalkState->Op = Op;
763    WalkState->Opcode = Op->Common.AmlOpcode;
764    WalkState->OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
765
766    /* Copy child pointer to Arg for compatibility with Interpreter */
767
768    if (Op->Asl.Child)
769    {
770        Op->Common.Value.Arg = Op->Asl.Child;
771    }
772
773    /* Call AML dispatcher */
774
775    Status = AcpiDsExecEndOp (WalkState);
776    if (ACPI_FAILURE (Status))
777    {
778        DbgPrint (ASL_PARSE_OUTPUT,
779            "%s: Constant interpretation failed (2) - %s\n",
780            Op->Asl.ParseOpName, AcpiFormatException (Status));
781    }
782
783    return (Status);
784}
785