Subversion Repositories Kolibri OS

Rev

Rev 1498 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1498 serge 1
 
2
 *
3
 * Module Name: asltree - parse tree management
4
 *
5
 *****************************************************************************/
6
7
 
8
 *
9
 * 1. Copyright Notice
10
 *
11
 * Some or all of this work - Copyright (c) 1999 - 2011, Intel Corp.
2216 Serge 12
 * All rights reserved.
1498 serge 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
#include "aslcompiler.y.h"
119
#include 
2216 Serge 120
1498 serge 121
 
122
        ACPI_MODULE_NAME    ("asltree")
123
124
 
125
126
 
127
TrGetNextNode (
128
    void);
129
130
 
131
TrGetNodeFlagName (
132
    UINT32                  Flags);
133
134
 
135
 
136
 *
137
 * FUNCTION:    TrGetNextNode
138
 *
139
 * PARAMETERS:  None
140
 *
141
 * RETURN:      New parse node.  Aborts on allocation failure
142
 *
143
 * DESCRIPTION: Allocate a new parse node for the parse tree.  Bypass the local
144
 *              dynamic memory manager for performance reasons (This has a
145
 *              major impact on the speed of the compiler.)
146
 *
147
 ******************************************************************************/
148
149
 
150
TrGetNextNode (
151
    void)
152
{
153
154
 
155
    {
156
        Gbl_NodeCacheNext = UtLocalCalloc (sizeof (ACPI_PARSE_OBJECT) *
157
                                ASL_NODE_CACHE_SIZE);
158
        Gbl_NodeCacheLast = Gbl_NodeCacheNext + ASL_NODE_CACHE_SIZE;
159
    }
160
161
 
162
}
163
164
 
165
 
166
 *
167
 * FUNCTION:    TrAllocateNode
168
 *
169
 * PARAMETERS:  ParseOpcode         - Opcode to be assigned to the node
170
 *
171
 * RETURN:      New parse node.  Aborts on allocation failure
172
 *
173
 * DESCRIPTION: Allocate and initialize a new parse node for the parse tree
174
 *
175
 ******************************************************************************/
176
177
 
178
TrAllocateNode (
179
    UINT32                  ParseOpcode)
180
{
181
    ACPI_PARSE_OBJECT       *Op;
182
183
 
184
 
185
186
 
187
    Op->Asl.Filename          = Gbl_Files[ASL_FILE_INPUT].Filename;
188
    Op->Asl.LineNumber        = Gbl_CurrentLineNumber;
189
    Op->Asl.LogicalLineNumber = Gbl_LogicalLineNumber;
190
    Op->Asl.LogicalByteOffset = Gbl_CurrentLineOffset;
191
    Op->Asl.Column            = Gbl_CurrentColumn;
192
193
 
194
    return Op;
195
}
196
197
 
198
 
199
 *
200
 * FUNCTION:    TrReleaseNode
201
 *
202
 * PARAMETERS:  Op            - Op to be released
203
 *
204
 * RETURN:      None
205
 *
206
 * DESCRIPTION: "release" a node.  In truth, nothing is done since the node
207
 *              is part of a larger buffer
208
 *
209
 ******************************************************************************/
210
211
 
212
TrReleaseNode (
213
    ACPI_PARSE_OBJECT       *Op)
214
{
215
216
 
217
}
218
219
 
220
 
221
 *
222
 * FUNCTION:    TrUpdateNode
223
 *
224
 * PARAMETERS:  ParseOpcode         - New opcode to be assigned to the node
225
 *              Op                - An existing parse node
226
 *
227
 * RETURN:      The updated node
228
 *
229
 * DESCRIPTION: Change the parse opcode assigned to a node.  Usually used to
230
 *              change an opcode to DEFAULT_ARG so that the node is ignored
231
 *              during the code generation.  Also used to set generic integers
232
 *              to a specific size (8, 16, 32, or 64 bits)
233
 *
234
 ******************************************************************************/
235
236
 
237
TrUpdateNode (
238
    UINT32                  ParseOpcode,
239
    ACPI_PARSE_OBJECT       *Op)
240
{
241
242
 
243
    {
244
        return NULL;
245
    }
246
247
 
248
        "\nUpdateNode: Old - %s, New - %s\n\n",
249
        UtGetOpName (Op->Asl.ParseOpcode),
250
        UtGetOpName (ParseOpcode));
251
252
 
253
254
 
255
    {
256
        switch (ParseOpcode)
257
        {
258
        case PARSEOP_BYTECONST:
259
            Op->Asl.Value.Integer = 0xFF;
260
            break;
261
262
 
263
            Op->Asl.Value.Integer = 0xFFFF;
264
            break;
265
266
 
267
            Op->Asl.Value.Integer = 0xFFFFFFFF;
268
            break;
269
270
 
271
            /* Don't care about others, don't need to check QWORD */
272
            break;
273
        }
274
    }
275
276
 
277
    UtSetParseOpName (Op);
278
279
 
280
     * For the BYTE, WORD, and DWORD constants, make sure that the integer
281
     * that was passed in will actually fit into the data type
282
     */
283
    switch (ParseOpcode)
284
    {
285
    case PARSEOP_BYTECONST:
286
        Op = UtCheckIntegerRange (Op, 0x00, ACPI_UINT8_MAX);
287
        break;
288
289
 
290
        Op = UtCheckIntegerRange (Op, 0x00, ACPI_UINT16_MAX);
291
        break;
292
293
 
294
        Op = UtCheckIntegerRange (Op, 0x00, ACPI_UINT32_MAX);
295
        break;
296
297
 
298
        /* Don't care about others, don't need to check QWORD */
299
        break;
300
    }
301
302
 
303
}
304
305
 
306
 
307
 *
308
 * FUNCTION:    TrGetNodeFlagName
309
 *
310
 * PARAMETERS:  Flags               - Flags word to be decoded
311
 *
312
 * RETURN:      Name string. Always returns a valid string pointer.
313
 *
314
 * DESCRIPTION: Decode a flags word
315
 *
316
 ******************************************************************************/
317
318
 
319
TrGetNodeFlagName (
320
    UINT32                  Flags)
321
{
322
323
 
324
    {
325
    case NODE_VISITED:
326
        return ("NODE_VISITED");
327
328
 
329
        return ("NODE_AML_PACKAGE");
330
331
 
332
        return ("NODE_IS_TARGET");
333
334
 
335
        return ("NODE_IS_RESOURCE_DESC");
336
337
 
338
        return ("NODE_IS_RESOURCE_FIELD");
339
340
 
341
        return ("NODE_HAS_NO_EXIT");
342
343
 
344
        return ("NODE_IF_HAS_NO_EXIT");
345
346
 
347
        return ("NODE_NAME_INTERNALIZED");
348
349
 
350
        return ("NODE_METHOD_NO_RETVAL");
351
352
 
353
        return ("NODE_METHOD_SOME_NO_RETVAL");
354
355
 
356
        return ("NODE_RESULT_NOT_USED");
357
358
 
359
        return ("NODE_METHOD_TYPED");
360
361
 
362
        return ("NODE_IS_BIT_OFFSET");
363
364
 
365
        return ("NODE_COMPILE_TIME_CONST");
366
367
 
368
        return ("NODE_IS_TERM_ARG");
369
370
 
371
        return ("NODE_WAS_ONES_OP");
372
373
 
374
        return ("NODE_IS_NAME_DECLARATION");
375
376
 
377
        return ("Multiple Flags (or unknown flag) set");
378
    }
379
}
380
381
 
382
 
383
 *
384
 * FUNCTION:    TrSetNodeFlags
385
 *
386
 * PARAMETERS:  Op                  - An existing parse node
387
 *              Flags               - New flags word
388
 *
389
 * RETURN:      The updated parser op
390
 *
391
 * DESCRIPTION: Set bits in the node flags word.  Will not clear bits, only set
392
 *
393
 ******************************************************************************/
394
395
 
396
TrSetNodeFlags (
397
    ACPI_PARSE_OBJECT       *Op,
398
    UINT32                  Flags)
399
{
400
401
 
402
        "\nSetNodeFlags: Op %p, %8.8X %s\n\n", Op, Flags,
403
        TrGetNodeFlagName (Flags));
404
405
 
406
    {
407
        return NULL;
408
    }
409
410
 
411
412
 
413
}
414
415
 
416
 
417
 *
418
 * FUNCTION:    TrSetEndLineNumber
419
 *
420
 * PARAMETERS:  Op                - An existing parse node
421
 *
422
 * RETURN:      None.
423
 *
424
 * DESCRIPTION: Set the ending line numbers (file line and logical line) of a
425
 *              parse node to the current line numbers.
426
 *
427
 ******************************************************************************/
428
429
 
430
TrSetEndLineNumber (
431
    ACPI_PARSE_OBJECT       *Op)
432
{
433
434
 
435
436
 
437
    {
438
        return;
439
    }
440
441
 
442
    Op->Asl.EndLogicalLine = Gbl_LogicalLineNumber;
443
}
444
445
 
446
 
447
 *
448
 * FUNCTION:    TrCreateLeafNode
449
 *
450
 * PARAMETERS:  ParseOpcode         - New opcode to be assigned to the node
451
 *
452
 * RETURN:      Pointer to the new node.  Aborts on allocation failure
453
 *
454
 * DESCRIPTION: Create a simple leaf node (no children or peers, and no value
455
 *              assigned to the node)
456
 *
457
 ******************************************************************************/
458
459
 
460
TrCreateLeafNode (
461
    UINT32                  ParseOpcode)
462
{
463
    ACPI_PARSE_OBJECT       *Op;
464
465
 
466
 
467
468
 
469
        "\nCreateLeafNode  Ln/Col %u/%u NewNode %p  Op %s\n\n",
470
        Op->Asl.LineNumber, Op->Asl.Column, Op, UtGetOpName(ParseOpcode));
471
472
 
473
}
474
475
 
476
 
477
 *
478
 * FUNCTION:    TrCreateConstantLeafNode
2216 Serge 479
 *
480
 * PARAMETERS:  ParseOpcode         - The constant opcode
481
 *
482
 * RETURN:      Pointer to the new node.  Aborts on allocation failure
483
 *
484
 * DESCRIPTION: Create a leaf node (no children or peers) for one of the
485
 *              special constants - __LINE__, __FILE__, and __DATE__.
486
 *
487
 * Note: An implemenation of __FUNC__ cannot happen here because we don't
488
 * have a full parse tree at this time and cannot find the parent control
489
 * method. If it is ever needed, __FUNC__ must be implemented later, after
490
 * the parse tree has been fully constructed.
491
 *
492
 ******************************************************************************/
493
494
 
495
TrCreateConstantLeafNode (
496
    UINT32                  ParseOpcode)
497
{
498
    ACPI_PARSE_OBJECT       *Op = NULL;
499
    time_t                  CurrentTime;
500
    char                    *StaticTimeString;
501
    char                    *TimeString;
502
503
 
504
 
505
    {
506
    case PARSEOP___LINE__:
507
        Op = TrAllocateNode (PARSEOP_INTEGER);
508
        Op->Asl.Value.Integer = Op->Asl.LineNumber;
509
        break;
510
511
 
512
        Op = TrAllocateNode (PARSEOP_STRING_LITERAL);
513
514
 
515
516
 
517
        break;
518
519
 
520
        Op = TrAllocateNode (PARSEOP_STRING_LITERAL);
521
522
 
523
524
 
525
        StaticTimeString = ctime (&CurrentTime);
526
        TimeString = UtLocalCalloc (strlen (StaticTimeString) + 1);
527
        strcpy (TimeString, StaticTimeString);
528
529
 
530
        Op->Asl.Value.String = TimeString;
531
        break;
532
533
 
534
        return (NULL);
535
    }
536
537
 
538
        "\nCreateConstantLeafNode  Ln/Col %u/%u NewNode %p  Op %s  Value %8.8X%8.8X  ",
539
        Op->Asl.LineNumber, Op->Asl.Column, Op, UtGetOpName (ParseOpcode),
540
        ACPI_FORMAT_UINT64 (Op->Asl.Value.Integer));
541
    return (Op);
542
}
543
544
 
545
 
546
 *
547
 * FUNCTION:    TrCreateValuedLeafNode
1498 serge 548
 *
549
 * PARAMETERS:  ParseOpcode         - New opcode to be assigned to the node
550
 *              Value               - Value to be assigned to the node
551
 *
552
 * RETURN:      Pointer to the new node.  Aborts on allocation failure
553
 *
554
 * DESCRIPTION: Create a leaf node (no children or peers) with a value
555
 *              assigned to it
556
 *
557
 ******************************************************************************/
558
559
 
560
TrCreateValuedLeafNode (
561
    UINT32                  ParseOpcode,
562
    UINT64                  Value)
563
{
564
    ACPI_PARSE_OBJECT       *Op;
565
566
 
567
 
568
569
 
570
        "\nCreateValuedLeafNode  Ln/Col %u/%u NewNode %p  Op %s  Value %8.8X%8.8X  ",
571
        Op->Asl.LineNumber, Op->Asl.Column, Op, UtGetOpName(ParseOpcode),
572
        ACPI_FORMAT_UINT64 (Value));
573
    Op->Asl.Value.Integer = Value;
574
575
 
576
    {
577
    case PARSEOP_STRING_LITERAL:
578
        DbgPrint (ASL_PARSE_OUTPUT, "STRING->%s", Value);
579
        break;
580
581
 
582
        DbgPrint (ASL_PARSE_OUTPUT, "NAMESEG->%s", Value);
583
        break;
584
585
 
586
        DbgPrint (ASL_PARSE_OUTPUT, "NAMESTRING->%s", Value);
587
        break;
588
589
 
590
        DbgPrint (ASL_PARSE_OUTPUT, "EISAID->%s", Value);
591
        break;
592
593
 
594
        DbgPrint (ASL_PARSE_OUTPUT, "METHOD");
595
        break;
596
597
 
598
        DbgPrint (ASL_PARSE_OUTPUT, "INTEGER");
599
        break;
600
601
 
602
        break;
603
    }
604
605
 
606
    return Op;
607
}
608
609
 
610
 
611
 *
612
 * FUNCTION:    TrCreateNode
613
 *
614
 * PARAMETERS:  ParseOpcode         - Opcode to be assigned to the node
615
 *              NumChildren         - Number of children to follow
616
 *              ...                 - A list of child nodes to link to the new
617
 *                                    node.  NumChildren long.
618
 *
619
 * RETURN:      Pointer to the new node.  Aborts on allocation failure
620
 *
621
 * DESCRIPTION: Create a new parse node and link together a list of child
622
 *              nodes underneath the new node.
623
 *
624
 ******************************************************************************/
625
626
 
627
TrCreateNode (
628
    UINT32                  ParseOpcode,
629
    UINT32                  NumChildren,
630
    ...)
631
{
632
    ACPI_PARSE_OBJECT       *Op;
633
    ACPI_PARSE_OBJECT       *Child;
634
    ACPI_PARSE_OBJECT       *PrevChild;
635
    va_list                 ap;
636
    UINT32                  i;
637
    BOOLEAN                 FirstChild;
638
639
 
640
 
641
642
 
643
644
 
645
646
 
647
        "\nCreateNode  Ln/Col %u/%u NewParent %p Child %u Op %s  ",
648
        Op->Asl.LineNumber, Op->Asl.Column, Op, NumChildren, UtGetOpName(ParseOpcode));
649
650
 
651
652
 
653
    {
654
    case PARSEOP_DEFINITIONBLOCK:
655
        RootNode = Op;
656
        DbgPrint (ASL_PARSE_OUTPUT, "DEFINITION_BLOCK (Tree Completed)->");
657
        break;
658
659
 
660
        DbgPrint (ASL_PARSE_OUTPUT, "OPREGION->");
661
        break;
662
663
 
664
        DbgPrint (ASL_PARSE_OUTPUT, "OR->");
665
        break;
666
667
 
668
        /* Nothing to do for other opcodes */
669
        break;
670
    }
671
672
 
673
674
 
675
    FirstChild = TRUE;
676
    for (i = 0; i < NumChildren; i++)
677
    {
678
        /* Get the next child */
679
680
 
681
        DbgPrint (ASL_PARSE_OUTPUT, "%p, ", Child);
682
683
 
684
         * If child is NULL, this means that an optional argument
685
         * was omitted.  We must create a placeholder with a special
686
         * opcode (DEFAULT_ARG) so that the code generator will know
687
         * that it must emit the correct default for this argument
688
         */
689
        if (!Child)
690
        {
691
            Child = TrAllocateNode (PARSEOP_DEFAULT_ARG);
692
        }
693
694
 
695
696
 
697
        {
698
            FirstChild = FALSE;
699
            Op->Asl.Child = Child;
700
        }
701
702
 
703
704
 
705
706
 
707
708
 
709
        {
710
            PrevChild->Asl.Next = Child;
711
        };
712
713
 
714
         * This child might be a list, point all nodes in the list
715
         * to the same parent
716
         */
717
        while (Child->Asl.Next)
718
        {
719
            Child = Child->Asl.Next;
720
            Child->Asl.Parent = Op;
721
        }
722
723
 
724
    }
725
    va_end(ap);
726
727
 
728
    return Op;
729
}
730
731
 
732
 
733
 *
734
 * FUNCTION:    TrLinkChildren
735
 *
736
 * PARAMETERS:  Op                - An existing parse node
737
 *              NumChildren         - Number of children to follow
738
 *              ...                 - A list of child nodes to link to the new
739
 *                                    node.  NumChildren long.
740
 *
741
 * RETURN:      The updated (linked) node
742
 *
743
 * DESCRIPTION: Link a group of nodes to an existing parse node
744
 *
745
 ******************************************************************************/
746
747
 
748
TrLinkChildren (
749
    ACPI_PARSE_OBJECT       *Op,
750
    UINT32                  NumChildren,
751
    ...)
752
{
753
    ACPI_PARSE_OBJECT       *Child;
754
    ACPI_PARSE_OBJECT       *PrevChild;
755
    va_list                 ap;
756
    UINT32                  i;
757
    BOOLEAN                 FirstChild;
758
759
 
760
 
761
762
 
763
 
764
765
 
766
        "\nLinkChildren  Line [%u to %u] NewParent %p Child %u Op %s  ",
767
        Op->Asl.LineNumber, Op->Asl.EndLine,
768
        Op, NumChildren, UtGetOpName(Op->Asl.ParseOpcode));
769
770
 
771
    {
772
    case PARSEOP_DEFINITIONBLOCK:
773
        RootNode = Op;
774
        DbgPrint (ASL_PARSE_OUTPUT, "DEFINITION_BLOCK (Tree Completed)->");
775
        break;
776
777
 
778
        DbgPrint (ASL_PARSE_OUTPUT, "OPREGION->");
779
        break;
780
781
 
782
        DbgPrint (ASL_PARSE_OUTPUT, "OR->");
783
        break;
784
785
 
786
        /* Nothing to do for other opcodes */
787
        break;
788
    }
789
790
 
791
792
 
793
    FirstChild = TRUE;
794
    for (i = 0; i < NumChildren; i++)
795
    {
796
        Child = va_arg (ap, ACPI_PARSE_OBJECT *);
797
798
 
799
        {
800
            AslError (ASL_WARNING, ASL_MSG_COMPILER_INTERNAL, Child,
801
                "Child node list invalid");
802
            return Op;
803
        }
804
805
 
806
807
 
808
         * If child is NULL, this means that an optional argument
809
         * was omitted.  We must create a placeholder with a special
810
         * opcode (DEFAULT_ARG) so that the code generator will know
811
         * that it must emit the correct default for this argument
812
         */
813
        if (!Child)
814
        {
815
            Child = TrAllocateNode (PARSEOP_DEFAULT_ARG);
816
        }
817
818
 
819
820
 
821
        {
822
            FirstChild = FALSE;
823
            Op->Asl.Child = Child;
824
        }
825
826
 
827
828
 
829
830
 
831
832
 
833
        {
834
            PrevChild->Asl.Next = Child;
835
        };
836
837
 
838
         * This child might be a list, point all nodes in the list
839
         * to the same parent
840
         */
841
        while (Child->Asl.Next)
842
        {
843
            Child = Child->Asl.Next;
844
            Child->Asl.Parent = Op;
845
        }
846
        PrevChild = Child;
847
    }
848
    va_end(ap);
849
850
 
851
    return Op;
852
}
853
854
 
855
 
856
 *
857
 * FUNCTION:    TrLinkPeerNode
858
 *
859
 * PARAMETERS:  Op1           - First peer
860
 *              Op2           - Second peer
861
 *
862
 * RETURN:      Op1 or the non-null node.
863
 *
864
 * DESCRIPTION: Link two nodes as peers.  Handles cases where one peer is null.
865
 *
866
 ******************************************************************************/
867
868
 
869
TrLinkPeerNode (
870
    ACPI_PARSE_OBJECT       *Op1,
871
    ACPI_PARSE_OBJECT       *Op2)
872
{
873
    ACPI_PARSE_OBJECT       *Next;
874
875
 
876
 
877
        "\nLinkPeerNode: 1=%p (%s), 2=%p (%s)\n\n",
878
        Op1, Op1 ? UtGetOpName(Op1->Asl.ParseOpcode) : NULL,
879
        Op2, Op2 ? UtGetOpName(Op2->Asl.ParseOpcode) : NULL);
880
881
 
882
 
883
    {
884
        DbgPrint (ASL_PARSE_OUTPUT, "\nTwo Null nodes!\n");
885
        return Op1;
886
    }
887
888
 
889
890
 
891
    {
892
        return Op1;
893
    }
894
895
 
896
    {
897
        return Op2;
898
    }
899
900
 
901
    {
902
        DbgPrint (ASL_DEBUG_OUTPUT,
903
            "\n\n************* Internal error, linking node to itself %p\n\n\n",
904
            Op1);
905
        AslError (ASL_WARNING, ASL_MSG_COMPILER_INTERNAL, Op1,
906
            "Linking node to itself");
907
        return Op1;
908
    }
909
910
 
911
912
 
913
     * Op 1 may already have a peer list (such as an IF/ELSE pair),
914
     * so we must walk to the end of the list and attach the new
915
     * peer at the end
916
     */
917
    Next = Op1;
918
    while (Next->Asl.Next)
919
    {
920
        Next = Next->Asl.Next;
921
    }
922
923
 
924
    return Op1;
925
}
926
927
 
928
 
929
 *
930
 * FUNCTION:    TrLinkPeerNodes
931
 *
932
 * PARAMETERS:  NumPeers            - The number of nodes in the list to follow
933
 *              ...                 - A list of nodes to link together as peers
934
 *
935
 * RETURN:      The first node in the list (head of the peer list)
936
 *
937
 * DESCRIPTION: Link together an arbitrary number of peer nodes.
938
 *
939
 ******************************************************************************/
940
941
 
942
TrLinkPeerNodes (
943
    UINT32                  NumPeers,
944
    ...)
945
{
946
    ACPI_PARSE_OBJECT       *This;
947
    ACPI_PARSE_OBJECT       *Next;
948
    va_list                 ap;
949
    UINT32                  i;
950
    ACPI_PARSE_OBJECT       *Start;
951
952
 
953
 
954
        "\nLinkPeerNodes: (%u) ", NumPeers);
955
956
 
957
    This = va_arg (ap, ACPI_PARSE_OBJECT *);
958
    Start = This;
959
960
 
961
     * Link all peers
962
     */
963
    for (i = 0; i < (NumPeers -1); i++)
964
    {
965
        DbgPrint (ASL_PARSE_OUTPUT, "%u=%p ", (i+1), This);
966
967
 
968
        {
969
            This = This->Asl.Next;
970
        }
971
972
 
973
974
 
975
        if (!Next)
976
        {
977
            Next = TrAllocateNode (PARSEOP_DEFAULT_ARG);
978
        }
979
980
 
981
982
 
983
        This = Next;
984
    }
985
    va_end (ap);
986
987
 
988
    return (Start);
989
}
990
991
 
992
 
993
 *
994
 * FUNCTION:    TrLinkChildNode
995
 *
996
 * PARAMETERS:  Op1           - Parent node
997
 *              Op2           - Op to become a child
998
 *
999
 * RETURN:      The parent node
1000
 *
1001
 * DESCRIPTION: Link two nodes together as a parent and child
1002
 *
1003
 ******************************************************************************/
1004
1005
 
1006
TrLinkChildNode (
1007
    ACPI_PARSE_OBJECT       *Op1,
1008
    ACPI_PARSE_OBJECT       *Op2)
1009
{
1010
    ACPI_PARSE_OBJECT       *Next;
1011
1012
 
1013
 
1014
        "\nLinkChildNode: Parent=%p (%s), Child=%p (%s)\n\n",
1015
        Op1, Op1 ? UtGetOpName(Op1->Asl.ParseOpcode): NULL,
1016
        Op2, Op2 ? UtGetOpName(Op2->Asl.ParseOpcode): NULL);
1017
1018
 
1019
    {
1020
        return Op1;
1021
    }
1022
1023
 
1024
1025
 
1026
1027
 
1028
    while (Next)
1029
    {
1030
        Next->Asl.Parent = Op1;
1031
        Next = Next->Asl.Next;
1032
    }
1033
1034
 
1035
}
1036
1037
 
1038
 
1039
 *
1040
 * FUNCTION:    TrWalkParseTree
1041
 *
1042
 * PARAMETERS:  Visitation              - Type of walk
1043
 *              DescendingCallback      - Called during tree descent
1044
 *              AscendingCallback       - Called during tree ascent
1045
 *              Context                 - To be passed to the callbacks
1046
 *
1047
 * RETURN:      Status from callback(s)
1048
 *
1049
 * DESCRIPTION: Walk the entire parse tree.
1050
 *
1051
 ******************************************************************************/
1052
1053
 
1054
TrWalkParseTree (
1055
    ACPI_PARSE_OBJECT       *Op,
1056
    UINT32                  Visitation,
1057
    ASL_WALK_CALLBACK       DescendingCallback,
1058
    ASL_WALK_CALLBACK       AscendingCallback,
1059
    void                    *Context)
1060
{
1061
    UINT32                  Level;
1062
    BOOLEAN                 NodePreviouslyVisited;
1063
    ACPI_PARSE_OBJECT       *StartOp = Op;
1064
    ACPI_STATUS             Status;
1065
1066
 
1067
 
1068
    {
1069
        return (AE_OK);
1070
    }
1071
1072
 
1073
    NodePreviouslyVisited = FALSE;
1074
1075
 
1076
    {
1077
    case ASL_WALK_VISIT_DOWNWARD:
1078
1079
 
1080
        {
1081
            if (!NodePreviouslyVisited)
1082
            {
1083
                /* Let the callback process the node. */
1084
1085
 
1086
                if (ACPI_SUCCESS (Status))
1087
                {
1088
                    /* Visit children first, once */
1089
1090
 
1091
                    {
1092
                        Level++;
1093
                        Op = Op->Asl.Child;
1094
                        continue;
1095
                    }
1096
                }
1097
                else if (Status != AE_CTRL_DEPTH)
1098
                {
1099
                    /* Exit immediately on any error */
1100
1101
 
1102
                }
1103
            }
1104
1105
 
1106
1107
 
1108
            {
1109
                break;
1110
            }
1111
1112
 
1113
1114
 
1115
            {
1116
                Op = Op->Asl.Next;
1117
                NodePreviouslyVisited = FALSE;
1118
            }
1119
            else
1120
            {
1121
                /* No children or peers, re-visit parent */
1122
1123
 
1124
                {
1125
                    Level--;
1126
                }
1127
                Op = Op->Asl.Parent;
1128
                NodePreviouslyVisited = TRUE;
1129
            }
1130
        }
1131
        break;
1132
1133
 
1134
 
1135
1136
 
1137
        {
1138
            /* Visit leaf node (no children) or parent node on return trip */
1139
1140
 
1141
                (NodePreviouslyVisited))
1142
            {
1143
                /* Let the callback process the node. */
1144
1145
 
1146
                if (ACPI_FAILURE (Status))
1147
                {
1148
                    return (Status);
1149
                }
1150
            }
1151
            else
1152
            {
1153
                /* Visit children first, once */
1154
1155
 
1156
                Op = Op->Asl.Child;
1157
                continue;
1158
            }
1159
1160
 
1161
1162
 
1163
            {
1164
                break;
1165
            }
1166
1167
 
1168
1169
 
1170
            {
1171
                Op = Op->Asl.Next;
1172
                NodePreviouslyVisited = FALSE;
1173
            }
1174
            else
1175
            {
1176
                /* No children or peers, re-visit parent */
1177
1178
 
1179
                {
1180
                    Level--;
1181
                }
1182
                Op = Op->Asl.Parent;
1183
                NodePreviouslyVisited = TRUE;
1184
            }
1185
        }
1186
        break;
1187
1188
 
1189
 
1190
1191
 
1192
        {
1193
            if (NodePreviouslyVisited)
1194
            {
1195
                Status = AscendingCallback (Op, Level, Context);
1196
                if (ACPI_FAILURE (Status))
1197
                {
1198
                    return (Status);
1199
                }
1200
            }
1201
            else
1202
            {
1203
                /* Let the callback process the node. */
1204
1205
 
1206
                if (ACPI_SUCCESS (Status))
1207
                {
1208
                    /* Visit children first, once */
1209
1210
 
1211
                    {
1212
                        Level++;
1213
                        Op = Op->Asl.Child;
1214
                        continue;
1215
                    }
1216
                }
1217
                else if (Status != AE_CTRL_DEPTH)
1218
                {
1219
                    /* Exit immediately on any error */
1220
1221
 
1222
                }
1223
            }
1224
1225
 
1226
1227
 
1228
            {
1229
                break;
1230
            }
1231
1232
 
1233
1234
 
1235
            {
1236
                Op = Op->Asl.Next;
1237
                NodePreviouslyVisited = FALSE;
1238
            }
1239
            else
1240
            {
1241
                /* No children or peers, re-visit parent */
1242
1243
 
1244
                {
1245
                    Level--;
1246
                }
1247
                Op = Op->Asl.Parent;
1248
                NodePreviouslyVisited = TRUE;
1249
            }
1250
        }
1251
        break;
1252
1253
 
1254
        /* No other types supported */
1255
        break;
1256
    }
1257
1258
 
1259
1260
 
1261
}
1262