Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1498 serge 1
 
2
 *
3
 * Module Name: aslanalyze.c - check for semantic errors
4
 *
5
 *****************************************************************************/
6
7
 
8
 *
9
 * 1. Copyright Notice
10
 *
11
 * Some or all of this work - Copyright (c) 1999 - 2010, 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
#include "aslcompiler.y.h"
119
#include "acparser.h"
120
#include "amlcode.h"
121
122
 
123
        ACPI_MODULE_NAME    ("aslanalyze")
124
125
 
126
127
 
128
AnMapArgTypeToBtype (
129
    UINT32                  ArgType);
130
131
 
132
AnMapEtypeToBtype (
133
    UINT32                  Etype);
134
135
 
136
AnFormatBtype (
137
    char                    *Buffer,
138
    UINT32                  Btype);
139
140
 
141
AnGetBtype (
142
    ACPI_PARSE_OBJECT       *Op);
143
144
 
145
AnMapObjTypeToBtype (
146
    ACPI_PARSE_OBJECT       *Op);
147
148
 
149
AnLastStatementIsReturn (
150
    ACPI_PARSE_OBJECT       *Op);
151
152
 
153
AnCheckMethodReturnValue (
154
    ACPI_PARSE_OBJECT       *Op,
155
    const ACPI_OPCODE_INFO  *OpInfo,
156
    ACPI_PARSE_OBJECT       *ArgOp,
157
    UINT32                  RequiredBtypes,
158
    UINT32                  ThisNodeBtype);
159
160
 
161
AnIsInternalMethod (
162
    ACPI_PARSE_OBJECT       *Op);
163
164
 
165
AnGetInternalMethodReturnType (
166
    ACPI_PARSE_OBJECT       *Op);
167
168
 
169
AnIsResultUsed (
170
    ACPI_PARSE_OBJECT       *Op);
171
172
 
173
 
174
 *
175
 * FUNCTION:    AnIsInternalMethod
176
 *
177
 * PARAMETERS:  Op              - Current op
178
 *
179
 * RETURN:      Boolean
180
 *
181
 * DESCRIPTION: Check for an internal control method.
182
 *
183
 ******************************************************************************/
184
185
 
186
AnIsInternalMethod (
187
    ACPI_PARSE_OBJECT       *Op)
188
{
189
190
 
191
        (!ACPI_STRCMP (Op->Asl.ExternalName, "_OSI")))
192
    {
193
        return (TRUE);
194
    }
195
196
 
197
}
198
199
 
200
 
201
 *
202
 * FUNCTION:    AnGetInternalMethodReturnType
203
 *
204
 * PARAMETERS:  Op              - Current op
205
 *
206
 * RETURN:      Btype
207
 *
208
 * DESCRIPTION: Get the return type of an internal method
209
 *
210
 ******************************************************************************/
211
212
 
213
AnGetInternalMethodReturnType (
214
    ACPI_PARSE_OBJECT       *Op)
215
{
216
217
 
218
        (!ACPI_STRCMP (Op->Asl.ExternalName, "_OSI")))
219
    {
220
        return (ACPI_BTYPE_STRING);
221
    }
222
223
 
224
}
225
226
 
227
 
228
 *
229
 * FUNCTION:    AnMapArgTypeToBtype
230
 *
231
 * PARAMETERS:  ArgType      - The ARGI required type(s) for this argument,
232
 *                             from the opcode info table
233
 *
234
 * RETURN:      The corresponding Bit-encoded types
235
 *
236
 * DESCRIPTION: Convert an encoded ARGI required argument type code into a
237
 *              bitfield type code. Implements the implicit source conversion
238
 *              rules.
239
 *
240
 ******************************************************************************/
241
242
 
243
AnMapArgTypeToBtype (
244
    UINT32                  ArgType)
245
{
246
247
 
248
    {
249
250
 
251
252
 
253
        return (ACPI_BTYPE_OBJECTS_AND_REFS);
254
255
 
256
        return (ACPI_BTYPE_PACKAGE);
257
258
 
259
        return (ACPI_BTYPE_EVENT);
260
261
 
262
        return (ACPI_BTYPE_MUTEX);
263
264
 
265
        /*
266
         * DDBHandleObject := SuperName
267
         * ACPI_BTYPE_REFERENCE: Index reference as parameter of Load/Unload
268
         */
269
        return (ACPI_BTYPE_DDB_HANDLE | ACPI_BTYPE_REFERENCE);
270
271
 
272
    /*
273
     * Source conversion rules:
274
     * Integer, String, and Buffer are all interchangeable
275
     */
276
    case ARGI_INTEGER:
277
    case ARGI_STRING:
278
    case ARGI_BUFFER:
279
    case ARGI_BUFFER_OR_STRING:
280
    case ARGI_COMPUTEDATA:
281
        return (ACPI_BTYPE_COMPUTE_DATA);
282
283
 
284
285
 
286
        return (ACPI_BTYPE_INTEGER);
287
288
 
289
        return (ACPI_BTYPE_ALL_OBJECTS);
290
291
 
292
        return (ACPI_BTYPE_DEVICE_OBJECTS);
293
294
 
295
        return (ACPI_BTYPE_REFERENCE);
296
297
 
298
    case ARGI_FIXED_TARGET:
299
    case ARGI_SIMPLE_TARGET:
300
        return (ACPI_BTYPE_OBJECTS_AND_REFS);
301
302
 
303
304
 
305
306
 
307
         * Buffer, string, package or reference to a Op -
308
         * Used only by SizeOf operator
309
         */
310
        return (ACPI_BTYPE_STRING | ACPI_BTYPE_BUFFER |
311
            ACPI_BTYPE_PACKAGE | ACPI_BTYPE_REFERENCE);
312
313
 
314
315
 
316
317
 
318
319
 
320
        return (ACPI_BTYPE_STRING | ACPI_BTYPE_REFERENCE);
321
322
 
323
324
 
325
326
 
327
328
 
329
        return (ACPI_BTYPE_INTEGER |ACPI_BTYPE_STRING | ACPI_BTYPE_BUFFER |
330
            ACPI_BTYPE_PACKAGE | ACPI_BTYPE_REFERENCE | ACPI_BTYPE_DDB_HANDLE);
331
332
 
333
        break;
334
    }
335
336
 
337
}
338
339
 
340
 
341
 *
342
 * FUNCTION:    AnMapEtypeToBtype
343
 *
344
 * PARAMETERS:  Etype           - Encoded ACPI Type
345
 *
346
 * RETURN:      Btype corresponding to the Etype
347
 *
348
 * DESCRIPTION: Convert an encoded ACPI type to a bitfield type applying the
349
 *              operand conversion rules. In other words, returns the type(s)
350
 *              this Etype is implicitly converted to during interpretation.
351
 *
352
 ******************************************************************************/
353
354
 
355
AnMapEtypeToBtype (
356
    UINT32                  Etype)
357
{
358
359
 
360
 
361
    {
362
        return ACPI_BTYPE_OBJECTS_AND_REFS;
363
    }
364
365
 
366
367
 
368
    {
369
        /*
370
         * This switch statement implements the allowed operand conversion
371
         * rules as per the "ASL Data Types" section of the ACPI
372
         * specification.
373
         */
374
        switch (Etype)
375
        {
376
        case ACPI_TYPE_INTEGER:
377
            return (ACPI_BTYPE_COMPUTE_DATA | ACPI_BTYPE_DDB_HANDLE);
378
379
 
380
        case ACPI_TYPE_BUFFER:
381
            return (ACPI_BTYPE_COMPUTE_DATA);
382
383
 
384
            return (ACPI_BTYPE_PACKAGE);
385
386
 
387
            return (ACPI_BTYPE_COMPUTE_DATA | ACPI_BTYPE_FIELD_UNIT);
388
389
 
390
            return (ACPI_BTYPE_COMPUTE_DATA | ACPI_BTYPE_BUFFER_FIELD);
391
392
 
393
            return (ACPI_BTYPE_INTEGER | ACPI_BTYPE_DDB_HANDLE);
394
395
 
396
397
 
398
399
 
400
401
 
402
            return (1 << (Etype - 1));
403
        }
404
    }
405
406
 
407
408
 
409
    {
410
    case ACPI_TYPE_LOCAL_REGION_FIELD:
411
    case ACPI_TYPE_LOCAL_BANK_FIELD:
412
    case ACPI_TYPE_LOCAL_INDEX_FIELD:
413
414
 
415
416
 
417
418
 
419
420
 
421
422
 
423
 
424
    case ACPI_TYPE_LOCAL_RESOURCE_FIELD:
425
426
 
427
428
 
429
        printf ("Unhandled encoded type: %X\n", Etype);
430
        return (0);
431
    }
432
}
433
434
 
435
 
436
 *
437
 * FUNCTION:    AnFormatBtype
438
 *
439
 * PARAMETERS:  Btype               - Bitfield of ACPI types
440
 *              Buffer              - Where to put the ascii string
441
 *
442
 * RETURN:      None.
443
 *
444
 * DESCRIPTION: Convert a Btype to a string of ACPI types
445
 *
446
 ******************************************************************************/
447
448
 
449
AnFormatBtype (
450
    char                    *Buffer,
451
    UINT32                  Btype)
452
{
453
    UINT32                  Type;
454
    BOOLEAN                 First = TRUE;
455
456
 
457
 
458
459
 
460
    {
461
        strcat (Buffer, "NoReturnValue");
462
        return;
463
    }
464
465
 
466
    {
467
        if (Btype & 0x00000001)
468
        {
469
            if (!First)
470
            {
471
                strcat (Buffer, "|");
472
            }
473
            First = FALSE;
474
            strcat (Buffer, AcpiUtGetTypeName (Type));
475
        }
476
        Btype >>= 1;
477
    }
478
479
 
480
    {
481
        if (!First)
482
        {
483
            strcat (Buffer, "|");
484
        }
485
        First = FALSE;
486
        strcat (Buffer, "Reference");
487
    }
488
489
 
490
    if (Btype & 0x00000001)
491
    {
492
        if (!First)
493
        {
494
            strcat (Buffer, "|");
495
        }
496
        First = FALSE;
497
        strcat (Buffer, "Resource");
498
    }
499
}
500
501
 
502
 
503
 *
504
 * FUNCTION:    AnGetBtype
505
 *
506
 * PARAMETERS:  Op          - Parse node whose type will be returned.
507
 *
508
 * RETURN:      The Btype associated with the Op.
509
 *
510
 * DESCRIPTION: Get the (bitfield) ACPI type associated with the parse node.
511
 *              Handles the case where the node is a name or method call and
512
 *              the actual type must be obtained from the namespace node.
513
 *
514
 ******************************************************************************/
515
516
 
517
AnGetBtype (
518
    ACPI_PARSE_OBJECT       *Op)
519
{
520
    ACPI_NAMESPACE_NODE     *Node;
521
    ACPI_PARSE_OBJECT       *ReferencedNode;
522
    UINT32                  ThisNodeBtype = 0;
523
524
 
525
 
526
        (Op->Asl.ParseOpcode == PARSEOP_NAMESTRING)  ||
527
        (Op->Asl.ParseOpcode == PARSEOP_METHODCALL))
528
    {
529
        Node = Op->Asl.Node;
530
        if (!Node)
531
        {
532
            DbgPrint (ASL_DEBUG_OUTPUT,
533
                "No attached Nsnode: [%s] at line %u name [%s], ignoring typecheck\n",
534
                Op->Asl.ParseOpName, Op->Asl.LineNumber,
535
                Op->Asl.ExternalName);
536
            return ACPI_UINT32_MAX;
537
        }
538
539
 
540
        if (!ThisNodeBtype)
541
        {
542
            AslError (ASL_ERROR, ASL_MSG_COMPILER_INTERNAL, Op,
543
                "could not map type");
544
        }
545
546
 
547
         * Since it was a named reference, enable the
548
         * reference bit also
549
         */
550
        ThisNodeBtype |= ACPI_BTYPE_REFERENCE;
551
552
 
553
        {
554
            ReferencedNode = Node->Op;
555
            if (!ReferencedNode)
556
            {
557
                /* Check for an internal method */
558
559
 
560
                {
561
                    return (AnGetInternalMethodReturnType (Op));
562
                }
563
564
 
565
                    "null Op pointer");
566
                return ACPI_UINT32_MAX;
567
            }
568
569
 
570
            {
571
                ThisNodeBtype = ReferencedNode->Asl.AcpiBtype;
572
            }
573
            else
574
            {
575
                return (ACPI_UINT32_MAX -1);
576
            }
577
        }
578
    }
579
    else
580
    {
581
        ThisNodeBtype = Op->Asl.AcpiBtype;
582
    }
583
584
 
585
}
586
587
 
588
 
589
 *
590
 * FUNCTION:    AnMapObjTypeToBtype
591
 *
592
 * PARAMETERS:  Op              - A parse node
593
 *
594
 * RETURN:      A Btype
595
 *
596
 * DESCRIPTION: Map object to the associated "Btype"
597
 *
598
 ******************************************************************************/
599
600
 
601
AnMapObjTypeToBtype (
602
    ACPI_PARSE_OBJECT       *Op)
603
{
604
605
 
606
    {
607
    case PARSEOP_OBJECTTYPE_BFF:        /* "BuffFieldObj" */
608
        return (ACPI_BTYPE_BUFFER_FIELD);
609
610
 
611
        return (ACPI_BTYPE_BUFFER);
612
613
 
614
        return (ACPI_BTYPE_DDB_HANDLE);
615
616
 
617
        return (ACPI_BTYPE_DEVICE);
618
619
 
620
        return (ACPI_BTYPE_EVENT);
621
622
 
623
        return (ACPI_BTYPE_FIELD_UNIT);
624
625
 
626
        return (ACPI_BTYPE_INTEGER);
627
628
 
629
        return (ACPI_BTYPE_METHOD);
630
631
 
632
        return (ACPI_BTYPE_MUTEX);
633
634
 
635
        return (ACPI_BTYPE_REGION);
636
637
 
638
        return (ACPI_BTYPE_PACKAGE);
639
640
 
641
        return (ACPI_BTYPE_POWER);
642
643
 
644
        return (ACPI_BTYPE_STRING);
645
646
 
647
        return (ACPI_BTYPE_THERMAL);
648
649
 
650
        return (ACPI_BTYPE_OBJECTS_AND_REFS);
651
652
 
653
        return (0);
654
    }
655
}
656
657
 
658
 
659
 *
660
 * FUNCTION:    AnMethodAnalysisWalkBegin
661
 *
662
 * PARAMETERS:  ASL_WALK_CALLBACK
663
 *
664
 * RETURN:      Status
665
 *
666
 * DESCRIPTION: Descending callback for the analysis walk. Check methods for:
667
 *              1) Initialized local variables
668
 *              2) Valid arguments
669
 *              3) Return types
670
 *
671
 ******************************************************************************/
672
673
 
674
AnMethodAnalysisWalkBegin (
675
    ACPI_PARSE_OBJECT       *Op,
676
    UINT32                  Level,
677
    void                    *Context)
678
{
679
    ASL_ANALYSIS_WALK_INFO  *WalkInfo = (ASL_ANALYSIS_WALK_INFO *) Context;
680
    ASL_METHOD_INFO         *MethodInfo = WalkInfo->MethodStack;
681
    ACPI_PARSE_OBJECT       *Next;
682
    UINT32                  RegisterNumber;
683
    UINT32                  i;
684
    char                    LocalName[] = "Local0";
685
    char                    ArgName[] = "Arg0";
686
    ACPI_PARSE_OBJECT       *ArgNode;
687
    ACPI_PARSE_OBJECT       *NextType;
688
    ACPI_PARSE_OBJECT       *NextParamType;
689
    UINT8                   ActualArgs = 0;
690
691
 
692
 
693
    {
694
    case PARSEOP_METHOD:
695
696
 
697
698
 
699
700
 
701
        MethodInfo->Next = WalkInfo->MethodStack;
702
        MethodInfo->Op = Op;
703
704
 
705
706
 
707
708
 
709
710
 
711
712
 
713
        MethodInfo->NumArguments = (UINT8)
714
            (((UINT8) Next->Asl.Value.Integer) & 0x07);
715
716
 
717
718
 
719
        Next = Next->Asl.Next;
720
        ArgNode = Next;
721
722
 
723
724
 
725
726
 
727
        while (NextType)
728
        {
729
            /* Get and map each of the ReturnTypes */
730
731
 
732
            NextType->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
733
            NextType = NextType->Asl.Next;
734
        }
735
736
 
737
738
 
739
740
 
741
        while (NextType)
742
        {
743
            if (NextType->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG)
744
            {
745
                NextParamType = NextType->Asl.Child;
746
                while (NextParamType)
747
                {
748
                    MethodInfo->ValidArgTypes[ActualArgs] |= AnMapObjTypeToBtype (NextParamType);
749
                    NextParamType->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
750
                    NextParamType = NextParamType->Asl.Next;
751
                }
752
            }
753
            else
754
            {
755
                MethodInfo->ValidArgTypes[ActualArgs] =
756
                    AnMapObjTypeToBtype (NextType);
757
                NextType->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
758
                ActualArgs++;
759
            }
760
761
 
762
        }
763
764
 
765
            (MethodInfo->NumArguments != ActualArgs))
766
        {
767
            /* error: Param list did not match number of args */
768
        }
769
770
 
771
772
 
773
        {
774
            MethodInfo->NumArguments = ActualArgs;
775
            ArgNode->Asl.Value.Integer |= ActualArgs;
776
        }
777
778
 
779
         * Actual arguments are initialized at method entry.
780
         * All other ArgX "registers" can be used as locals, so we
781
         * track their initialization.
782
         */
783
        for (i = 0; i < MethodInfo->NumArguments; i++)
784
        {
785
            MethodInfo->ArgInitialized[i] = TRUE;
786
        }
787
        break;
788
789
 
790
 
791
792
 
793
           (Op->Asl.Node == MethodInfo->Op->Asl.Node))
794
        {
795
            AslError (ASL_REMARK, ASL_MSG_RECURSION, Op, Op->Asl.ExternalName);
796
        }
797
        break;
798
799
 
800
 
801
    case PARSEOP_LOCAL1:
802
    case PARSEOP_LOCAL2:
803
    case PARSEOP_LOCAL3:
804
    case PARSEOP_LOCAL4:
805
    case PARSEOP_LOCAL5:
806
    case PARSEOP_LOCAL6:
807
    case PARSEOP_LOCAL7:
808
809
 
810
        {
811
            /*
812
             * Local was used outside a control method, or there was an error
813
             * in the method declaration.
814
             */
815
            AslError (ASL_REMARK, ASL_MSG_LOCAL_OUTSIDE_METHOD, Op, Op->Asl.ExternalName);
816
            return (AE_ERROR);
817
        }
818
819
 
820
821
 
822
         * If the local is being used as a target, mark the local
823
         * initialized
824
         */
825
        if (Op->Asl.CompileFlags & NODE_IS_TARGET)
826
        {
827
            MethodInfo->LocalInitialized[RegisterNumber] = TRUE;
828
        }
829
830
 
831
         * Otherwise, this is a reference, check if the local
832
         * has been previously initialized.
833
         *
834
         * The only operator that accepts an uninitialized value is ObjectType()
835
         */
836
        else if ((!MethodInfo->LocalInitialized[RegisterNumber]) &&
837
                 (Op->Asl.Parent->Asl.ParseOpcode != PARSEOP_OBJECTTYPE))
838
        {
839
            LocalName[strlen (LocalName) -1] = (char) (RegisterNumber + 0x30);
840
            AslError (ASL_ERROR, ASL_MSG_LOCAL_INIT, Op, LocalName);
841
        }
842
        break;
843
844
 
845
 
846
    case PARSEOP_ARG1:
847
    case PARSEOP_ARG2:
848
    case PARSEOP_ARG3:
849
    case PARSEOP_ARG4:
850
    case PARSEOP_ARG5:
851
    case PARSEOP_ARG6:
852
853
 
854
        {
855
            /*
856
             * Arg was used outside a control method, or there was an error
857
             * in the method declaration.
858
             */
859
            AslError (ASL_REMARK, ASL_MSG_LOCAL_OUTSIDE_METHOD, Op, Op->Asl.ExternalName);
860
            return (AE_ERROR);
861
        }
862
863
 
864
        ArgName[strlen (ArgName) -1] = (char) (RegisterNumber + 0x30);
865
866
 
867
         * If the Arg is being used as a target, mark the local
868
         * initialized
869
         */
870
        if (Op->Asl.CompileFlags & NODE_IS_TARGET)
871
        {
872
            MethodInfo->ArgInitialized[RegisterNumber] = TRUE;
873
        }
874
875
 
876
         * Otherwise, this is a reference, check if the Arg
877
         * has been previously initialized.
878
         *
879
         * The only operator that accepts an uninitialized value is ObjectType()
880
         */
881
        else if ((!MethodInfo->ArgInitialized[RegisterNumber]) &&
882
                 (Op->Asl.Parent->Asl.ParseOpcode != PARSEOP_OBJECTTYPE))
883
        {
884
            AslError (ASL_ERROR, ASL_MSG_ARG_INIT, Op, ArgName);
885
        }
886
887
 
888
889
 
890
        {
891
            AslError (ASL_REMARK, ASL_MSG_NOT_PARAMETER, Op, ArgName);
892
        }
893
        break;
894
895
 
896
 
897
898
 
899
        {
900
            /*
901
             * Probably was an error in the method declaration,
902
             * no additional error here
903
             */
904
            ACPI_WARNING ((AE_INFO, "%p, No parent method", Op));
905
            return (AE_ERROR);
906
        }
907
908
 
909
910
 
911
            (Op->Asl.Child->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG))
912
        {
913
            MethodInfo->NumReturnWithValue++;
914
        }
915
        else
916
        {
917
            MethodInfo->NumReturnNoValue++;
918
        }
919
        break;
920
921
 
922
 
923
    case PARSEOP_CONTINUE:
924
925
 
926
        while (Next)
927
        {
928
            if (Next->Asl.ParseOpcode == PARSEOP_WHILE)
929
            {
930
                break;
931
            }
932
            Next = Next->Asl.Parent;
933
        }
934
935
 
936
        {
937
            AslError (ASL_ERROR, ASL_MSG_NO_WHILE, Op, NULL);
938
        }
939
        break;
940
941
 
942
 
943
944
 
945
946
 
947
            (Op->Asl.Child->Asl.Value.Integer > ACPI_UINT8_MAX))
948
        {
949
            AslError (ASL_ERROR, ASL_MSG_INVALID_TIME, Op, NULL);
950
        }
951
        break;
952
953
 
954
 
955
    case PARSEOP_EVENT:
956
    case PARSEOP_MUTEX:
957
    case PARSEOP_OPERATIONREGION:
958
    case PARSEOP_POWERRESOURCE:
959
    case PARSEOP_PROCESSOR:
960
    case PARSEOP_THERMALZONE:
961
962
 
963
         * The first operand is a name to be created in the namespace.
964
         * Check against the reserved list.
965
         */
966
        i = ApCheckForPredefinedName (Op, Op->Asl.NameSeg);
967
        if (i < ACPI_VALID_RESERVED_NAME_MAX)
968
        {
969
            AslError (ASL_ERROR, ASL_MSG_RESERVED_USE, Op, Op->Asl.ExternalName);
970
        }
971
        break;
972
973
 
974
 
975
976
 
977
978
 
979
980
 
981
982
 
983
        {
984
            Next = Op->Asl.Child->Asl.Next;
985
            if (Next->Asl.ParseOpcode == PARSEOP_STRING_LITERAL)
986
            {
987
                /*
988
                 * _HID is a string, all characters must be alphanumeric.
989
                 * One of the things we want to catch here is the use of
990
                 * a leading asterisk in the string.
991
                 */
992
                for (i = 0; Next->Asl.Value.String[i]; i++)
993
                {
994
                    if (!isalnum ((int) Next->Asl.Value.String[i]))
995
                    {
996
                        AslError (ASL_ERROR, ASL_MSG_ALPHANUMERIC_STRING,
997
                            Next, Next->Asl.Value.String);
998
                        break;
999
                    }
1000
                }
1001
            }
1002
        }
1003
        break;
1004
1005
 
1006
 
1007
        break;
1008
    }
1009
1010
 
1011
}
1012
1013
 
1014
 
1015
 *
1016
 * FUNCTION:    AnLastStatementIsReturn
1017
 *
1018
 * PARAMETERS:  Op            - A method parse node
1019
 *
1020
 * RETURN:      TRUE if last statement is an ASL RETURN. False otherwise
1021
 *
1022
 * DESCRIPTION: Walk down the list of top level statements within a method
1023
 *              to find the last one. Check if that last statement is in
1024
 *              fact a RETURN statement.
1025
 *
1026
 ******************************************************************************/
1027
1028
 
1029
AnLastStatementIsReturn (
1030
    ACPI_PARSE_OBJECT       *Op)
1031
{
1032
    ACPI_PARSE_OBJECT       *Next;
1033
1034
 
1035
 
1036
     * Check if last statement is a return
1037
     */
1038
    Next = ASL_GET_CHILD_NODE (Op);
1039
    while (Next)
1040
    {
1041
        if ((!Next->Asl.Next) &&
1042
            (Next->Asl.ParseOpcode == PARSEOP_RETURN))
1043
        {
1044
            return TRUE;
1045
        }
1046
1047
 
1048
    }
1049
1050
 
1051
}
1052
1053
 
1054
 
1055
 *
1056
 * FUNCTION:    AnMethodAnalysisWalkEnd
1057
 *
1058
 * PARAMETERS:  ASL_WALK_CALLBACK
1059
 *
1060
 * RETURN:      Status
1061
 *
1062
 * DESCRIPTION: Ascending callback for analysis walk. Complete method
1063
 *              return analysis.
1064
 *
1065
 ******************************************************************************/
1066
1067
 
1068
AnMethodAnalysisWalkEnd (
1069
    ACPI_PARSE_OBJECT       *Op,
1070
    UINT32                  Level,
1071
    void                    *Context)
1072
{
1073
    ASL_ANALYSIS_WALK_INFO  *WalkInfo = (ASL_ANALYSIS_WALK_INFO *) Context;
1074
    ASL_METHOD_INFO         *MethodInfo = WalkInfo->MethodStack;
1075
1076
 
1077
 
1078
    {
1079
    case PARSEOP_METHOD:
1080
    case PARSEOP_RETURN:
1081
        if (!MethodInfo)
1082
        {
1083
            printf ("No method info for method! [%s]\n", Op->Asl.Namepath);
1084
            AslError (ASL_ERROR, ASL_MSG_COMPILER_INTERNAL, Op,
1085
                "No method info for this method");
1086
            CmCleanupAndExit ();
1087
            return (AE_AML_INTERNAL);
1088
        }
1089
        break;
1090
1091
 
1092
        break;
1093
    }
1094
1095
 
1096
    {
1097
    case PARSEOP_METHOD:
1098
1099
 
1100
1101
 
1102
         * Check if there is no return statement at the end of the
1103
         * method AND we can actually get there -- i.e., the execution
1104
         * of the method can possibly terminate without a return statement.
1105
         */
1106
        if ((!AnLastStatementIsReturn (Op)) &&
1107
            (!(Op->Asl.CompileFlags & NODE_HAS_NO_EXIT)))
1108
        {
1109
            /*
1110
             * No return statement, and execution can possibly exit
1111
             * via this path. This is equivalent to Return ()
1112
             */
1113
            MethodInfo->NumReturnNoValue++;
1114
        }
1115
1116
 
1117
         * Check for case where some return statements have a return value
1118
         * and some do not. Exit without a return statement is a return with
1119
         * no value
1120
         */
1121
        if (MethodInfo->NumReturnNoValue &&
1122
            MethodInfo->NumReturnWithValue)
1123
        {
1124
            AslError (ASL_WARNING, ASL_MSG_RETURN_TYPES, Op,
1125
                Op->Asl.ExternalName);
1126
        }
1127
1128
 
1129
         * If there are any RETURN() statements with no value, or there is a
1130
         * control path that allows the method to exit without a return value,
1131
         * we mark the method as a method that does not return a value. This
1132
         * knowledge can be used to check method invocations that expect a
1133
         * returned value.
1134
         */
1135
        if (MethodInfo->NumReturnNoValue)
1136
        {
1137
            if (MethodInfo->NumReturnWithValue)
1138
            {
1139
                Op->Asl.CompileFlags |= NODE_METHOD_SOME_NO_RETVAL;
1140
            }
1141
            else
1142
            {
1143
                Op->Asl.CompileFlags |= NODE_METHOD_NO_RETVAL;
1144
            }
1145
        }
1146
1147
 
1148
         * Check predefined method names for correct return behavior
1149
         * and correct number of arguments
1150
         */
1151
        ApCheckForPredefinedMethod (Op, MethodInfo);
1152
        ACPI_FREE (MethodInfo);
1153
        break;
1154
1155
 
1156
 
1157
1158
 
1159
         * If the parent is a predefined method name, attempt to typecheck
1160
         * the return value. Only static types can be validated.
1161
         */
1162
        ApCheckPredefinedReturnValue (Op, MethodInfo);
1163
1164
 
1165
         * The parent block does not "exit" and continue execution -- the
1166
         * method is terminated here with the Return() statement.
1167
         */
1168
        Op->Asl.Parent->Asl.CompileFlags |= NODE_HAS_NO_EXIT;
1169
1170
 
1171
1172
 
1173
1174
 
1175
         * If there is a peer node after the return statement, then this
1176
         * node is unreachable code -- i.e., it won't be executed because of
1177
         * the preceeding Return() statement.
1178
         */
1179
        if (Op->Asl.Next)
1180
        {
1181
            AslError (ASL_WARNING, ASL_MSG_UNREACHABLE_CODE, Op->Asl.Next, NULL);
1182
        }
1183
        break;
1184
1185
 
1186
 
1187
1188
 
1189
            (Op->Asl.Next) &&
1190
            (Op->Asl.Next->Asl.ParseOpcode == PARSEOP_ELSE))
1191
        {
1192
            /*
1193
             * This IF has a corresponding ELSE. The IF block has no exit,
1194
             * (it contains an unconditional Return)
1195
             * mark the ELSE block to remember this fact.
1196
             */
1197
            Op->Asl.Next->Asl.CompileFlags |= NODE_IF_HAS_NO_EXIT;
1198
        }
1199
        break;
1200
1201
 
1202
 
1203
1204
 
1205
            (Op->Asl.CompileFlags & NODE_IF_HAS_NO_EXIT))
1206
        {
1207
            /*
1208
             * This ELSE block has no exit and the corresponding IF block
1209
             * has no exit either. Therefore, the parent node has no exit.
1210
             */
1211
            Op->Asl.Parent->Asl.CompileFlags |= NODE_HAS_NO_EXIT;
1212
        }
1213
        break;
1214
1215
 
1216
 
1217
1218
 
1219
            (Op->Asl.Parent))
1220
        {
1221
            /* If this node has no exit, then the parent has no exit either */
1222
1223
 
1224
        }
1225
        break;
1226
    }
1227
1228
 
1229
}
1230
1231
 
1232
 
1233
 *
1234
 * FUNCTION:    AnMethodTypingWalkBegin
1235
 *
1236
 * PARAMETERS:  ASL_WALK_CALLBACK
1237
 *
1238
 * RETURN:      Status
1239
 *
1240
 * DESCRIPTION: Descending callback for the typing walk.
1241
 *
1242
 ******************************************************************************/
1243
1244
 
1245
AnMethodTypingWalkBegin (
1246
    ACPI_PARSE_OBJECT       *Op,
1247
    UINT32                  Level,
1248
    void                    *Context)
1249
{
1250
1251
 
1252
}
1253
1254
 
1255
 
1256
 *
1257
 * FUNCTION:    AnMethodTypingWalkEnd
1258
 *
1259
 * PARAMETERS:  ASL_WALK_CALLBACK
1260
 *
1261
 * RETURN:      Status
1262
 *
1263
 * DESCRIPTION: Ascending callback for typing walk. Complete the method
1264
 *              return analysis. Check methods for:
1265
 *              1) Initialized local variables
1266
 *              2) Valid arguments
1267
 *              3) Return types
1268
 *
1269
 ******************************************************************************/
1270
1271
 
1272
AnMethodTypingWalkEnd (
1273
    ACPI_PARSE_OBJECT       *Op,
1274
    UINT32                  Level,
1275
    void                    *Context)
1276
{
1277
    UINT32                  ThisNodeBtype;
1278
1279
 
1280
 
1281
    {
1282
    case PARSEOP_METHOD:
1283
1284
 
1285
        break;
1286
1287
 
1288
1289
 
1290
            (Op->Asl.Child->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG))
1291
        {
1292
            ThisNodeBtype = AnGetBtype (Op->Asl.Child);
1293
1294
 
1295
                (ThisNodeBtype == (ACPI_UINT32_MAX -1)))
1296
            {
1297
                /*
1298
                 * The called method is untyped at this time (typically a
1299
                 * forward reference).
1300
                 *
1301
                 * Check for a recursive method call first.
1302
                 */
1303
                if (Op->Asl.ParentMethod != Op->Asl.Child->Asl.Node->Op)
1304
                {
1305
                    /* We must type the method here */
1306
1307
 
1308
                        ASL_WALK_VISIT_TWICE, AnMethodTypingWalkBegin,
1309
                        AnMethodTypingWalkEnd, NULL);
1310
1311
 
1312
                }
1313
            }
1314
1315
 
1316
1317
 
1318
            {
1319
                Op->Asl.ParentMethod->Asl.AcpiBtype |= ThisNodeBtype;
1320
            }
1321
        }
1322
        break;
1323
1324
 
1325
        break;
1326
    }
1327
1328
 
1329
}
1330
1331
 
1332
 
1333
 *
1334
 * FUNCTION:    AnCheckMethodReturnValue
1335
 *
1336
 * PARAMETERS:  Op                  - Parent
1337
 *              OpInfo              - Parent info
1338
 *              ArgOp               - Method invocation op
1339
 *              RequiredBtypes      - What caller requires
1340
 *              ThisNodeBtype       - What this node returns (if anything)
1341
 *
1342
 * RETURN:      None
1343
 *
1344
 * DESCRIPTION: Check a method invocation for 1) A return value and if it does
1345
 *              in fact return a value, 2) check the type of the return value.
1346
 *
1347
 ******************************************************************************/
1348
1349
 
1350
AnCheckMethodReturnValue (
1351
    ACPI_PARSE_OBJECT       *Op,
1352
    const ACPI_OPCODE_INFO  *OpInfo,
1353
    ACPI_PARSE_OBJECT       *ArgOp,
1354
    UINT32                  RequiredBtypes,
1355
    UINT32                  ThisNodeBtype)
1356
{
1357
    ACPI_PARSE_OBJECT       *OwningOp;
1358
    ACPI_NAMESPACE_NODE     *Node;
1359
1360
 
1361
 
1362
1363
 
1364
 
1365
1366
 
1367
    if (OwningOp->Asl.CompileFlags & NODE_METHOD_NO_RETVAL)
1368
    {
1369
        /* Method NEVER returns a value */
1370
1371
 
1372
    }
1373
    else if (OwningOp->Asl.CompileFlags & NODE_METHOD_SOME_NO_RETVAL)
1374
    {
1375
        /* Method SOMETIMES returns a value, SOMETIMES not */
1376
1377
 
1378
    }
1379
    else if (!(ThisNodeBtype & RequiredBtypes))
1380
    {
1381
        /* Method returns a value, but the type is wrong */
1382
1383
 
1384
        AnFormatBtype (StringBuffer2, RequiredBtypes);
1385
1386
 
1387
 
1388
         * The case where the method does not return any value at all
1389
         * was already handled in the namespace cross reference
1390
         * -- Only issue an error if the method in fact returns a value,
1391
         * but it is of the wrong type
1392
         */
1393
        if (ThisNodeBtype != 0)
1394
        {
1395
            sprintf (MsgBuffer,
1396
                "Method returns [%s], %s operator requires [%s]",
1397
                StringBuffer, OpInfo->Name, StringBuffer2);
1398
1399
 
1400
        }
1401
    }
1402
}
1403
1404
 
1405
 
1406
 *
1407
 * FUNCTION:    AnOperandTypecheckWalkBegin
1408
 *
1409
 * PARAMETERS:  ASL_WALK_CALLBACK
1410
 *
1411
 * RETURN:      Status
1412
 *
1413
 * DESCRIPTION: Descending callback for the analysis walk. Check methods for:
1414
 *              1) Initialized local variables
1415
 *              2) Valid arguments
1416
 *              3) Return types
1417
 *
1418
 ******************************************************************************/
1419
1420
 
1421
AnOperandTypecheckWalkBegin (
1422
    ACPI_PARSE_OBJECT       *Op,
1423
    UINT32                  Level,
1424
    void                    *Context)
1425
{
1426
1427
 
1428
}
1429
1430
 
1431
 
1432
 *
1433
 * FUNCTION:    AnOperandTypecheckWalkEnd
1434
 *
1435
 * PARAMETERS:  ASL_WALK_CALLBACK
1436
 *
1437
 * RETURN:      Status
1438
 *
1439
 * DESCRIPTION: Ascending callback for analysis walk. Complete method
1440
 *              return analysis.
1441
 *
1442
 ******************************************************************************/
1443
1444
 
1445
AnOperandTypecheckWalkEnd (
1446
    ACPI_PARSE_OBJECT       *Op,
1447
    UINT32                  Level,
1448
    void                    *Context)
1449
{
1450
    const ACPI_OPCODE_INFO  *OpInfo;
1451
    UINT32                  RuntimeArgTypes;
1452
    UINT32                  RuntimeArgTypes2;
1453
    UINT32                  RequiredBtypes;
1454
    UINT32                  ThisNodeBtype;
1455
    UINT32                  CommonBtypes;
1456
    UINT32                  OpcodeClass;
1457
    ACPI_PARSE_OBJECT       *ArgOp;
1458
    UINT32                  ArgType;
1459
1460
 
1461
 
1462
    {
1463
    case AML_RAW_DATA_BYTE:
1464
    case AML_RAW_DATA_WORD:
1465
    case AML_RAW_DATA_DWORD:
1466
    case AML_RAW_DATA_QWORD:
1467
    case AML_RAW_DATA_BUFFER:
1468
    case AML_RAW_DATA_CHAIN:
1469
    case AML_PACKAGE_LENGTH:
1470
    case AML_UNASSIGNED_OPCODE:
1471
    case AML_DEFAULT_ARG_OP:
1472
1473
 
1474
1475
 
1476
1477
 
1478
        break;
1479
    }
1480
1481
 
1482
    if (!OpInfo)
1483
    {
1484
        return (AE_OK);
1485
    }
1486
1487
 
1488
    RuntimeArgTypes = OpInfo->RuntimeArgs;
1489
    OpcodeClass     = OpInfo->Class;
1490
1491
 
1492
    /*
1493
     * Update 11/2008: In practice, we can't perform this check. A simple
1494
     * analysis is not sufficient. Also, it can cause errors when compiling
1495
     * disassembled code because of the way Switch operators are implemented
1496
     * (a While(One) loop with a named temp variable created within.)
1497
     */
1498
1499
 
1500
     * If we are creating a named object, check if we are within a while loop
1501
     * by checking if the parent is a WHILE op. This is a simple analysis, but
1502
     * probably sufficient for many cases.
1503
     *
1504
     * Allow Scope(), Buffer(), and Package().
1505
     */
1506
    if (((OpcodeClass == AML_CLASS_NAMED_OBJECT) && (Op->Asl.AmlOpcode != AML_SCOPE_OP)) ||
1507
        ((OpcodeClass == AML_CLASS_CREATE) && (OpInfo->Flags & AML_NSNODE)))
1508
    {
1509
        if (Op->Asl.Parent->Asl.AmlOpcode == AML_WHILE_OP)
1510
        {
1511
            AslError (ASL_ERROR, ASL_MSG_NAMED_OBJECT_IN_WHILE, Op, NULL);
1512
        }
1513
    }
1514
#endif
1515
1516
 
1517
     * Special case for control opcodes IF/RETURN/WHILE since they
1518
     * have no runtime arg list (at this time)
1519
     */
1520
    switch (Op->Asl.AmlOpcode)
1521
    {
1522
    case AML_IF_OP:
1523
    case AML_WHILE_OP:
1524
    case AML_RETURN_OP:
1525
1526
 
1527
        {
1528
            /* Check for an internal method */
1529
1530
 
1531
            {
1532
                return (AE_OK);
1533
            }
1534
1535
 
1536
1537
 
1538
            if (Op->Asl.AmlOpcode == AML_RETURN_OP)
1539
            {
1540
                RequiredBtypes = 0xFFFFFFFF;
1541
            }
1542
1543
 
1544
            if (ThisNodeBtype == ACPI_UINT32_MAX)
1545
            {
1546
                return (AE_OK);
1547
            }
1548
            AnCheckMethodReturnValue (Op, OpInfo, ArgOp,
1549
                RequiredBtypes, ThisNodeBtype);
1550
        }
1551
        return (AE_OK);
1552
1553
 
1554
        break;
1555
    }
1556
1557
 
1558
1559
 
1560
    {
1561
        return (AE_OK);
1562
    }
1563
1564
 
1565
    {
1566
    case AML_CLASS_EXECUTE:
1567
    case AML_CLASS_CREATE:
1568
    case AML_CLASS_CONTROL:
1569
    case AML_CLASS_RETURN_VALUE:
1570
1571
 
1572
1573
 
1574
            (Op->Asl.AmlOpcode == AML_PACKAGE_OP)       ||
1575
            (Op->Asl.AmlOpcode == AML_VAR_PACKAGE_OP))
1576
        {
1577
            break;
1578
        }
1579
1580
 
1581
1582
 
1583
        while ((ArgType = GET_CURRENT_ARG_TYPE (RuntimeArgTypes)))
1584
        {
1585
            RuntimeArgTypes2 <<= ARG_TYPE_WIDTH;
1586
            RuntimeArgTypes2 |= ArgType;
1587
            INCREMENT_ARG_LIST (RuntimeArgTypes);
1588
        }
1589
1590
 
1591
        {
1592
            RequiredBtypes = AnMapArgTypeToBtype (ArgType);
1593
1594
 
1595
            if (ThisNodeBtype == ACPI_UINT32_MAX)
1596
            {
1597
                goto NextArgument;
1598
            }
1599
1600
 
1601
1602
 
1603
            {
1604
            case ARGI_TARGETREF:
1605
1606
 
1607
                {
1608
                    /* ZERO is the placeholder for "don't store result" */
1609
1610
 
1611
                    break;
1612
                }
1613
1614
 
1615
                {
1616
                    /*
1617
                     * This is the case where an original reference to a resource
1618
                     * descriptor field has been replaced by an (Integer) offset.
1619
                     * These named fields are supported at compile-time only;
1620
                     * the names are not passed to the interpreter (via the AML).
1621
                     */
1622
                    if ((ArgOp->Asl.Node->Type == ACPI_TYPE_LOCAL_RESOURCE_FIELD) ||
1623
                        (ArgOp->Asl.Node->Type == ACPI_TYPE_LOCAL_RESOURCE))
1624
                    {
1625
                        AslError (ASL_ERROR, ASL_MSG_RESOURCE_FIELD, ArgOp, NULL);
1626
                    }
1627
                    else
1628
                    {
1629
                        AslError (ASL_ERROR, ASL_MSG_INVALID_TYPE, ArgOp, NULL);
1630
                    }
1631
                    break;
1632
                }
1633
1634
 
1635
                    (ArgOp->Asl.ParseOpcode == PARSEOP_DEREFOF))
1636
                {
1637
                    break;
1638
                }
1639
1640
 
1641
                break;
1642
1643
 
1644
 
1645
            case ARGI_INTEGER_REF:
1646
            case ARGI_OBJECT_REF:
1647
            case ARGI_DEVICE_REF:
1648
1649
 
1650
                {
1651
                case PARSEOP_LOCAL0:
1652
                case PARSEOP_LOCAL1:
1653
                case PARSEOP_LOCAL2:
1654
                case PARSEOP_LOCAL3:
1655
                case PARSEOP_LOCAL4:
1656
                case PARSEOP_LOCAL5:
1657
                case PARSEOP_LOCAL6:
1658
                case PARSEOP_LOCAL7:
1659
1660
 
1661
                    /* For now, just treat any local as a typematch */
1662
1663
 
1664
                    break;
1665
1666
 
1667
                case PARSEOP_ARG1:
1668
                case PARSEOP_ARG2:
1669
                case PARSEOP_ARG3:
1670
                case PARSEOP_ARG4:
1671
                case PARSEOP_ARG5:
1672
                case PARSEOP_ARG6:
1673
1674
 
1675
                    /* For now, just treat any arg as a typematch */
1676
1677
 
1678
                    break;
1679
1680
 
1681
                    break;
1682
1683
 
1684
                case PARSEOP_INDEX:
1685
                default:
1686
                    break;
1687
1688
 
1689
                break;
1690
1691
 
1692
            default:
1693
                break;
1694
            }
1695
1696
 
1697
 
1698
1699
 
1700
            {
1701
                if (AnIsInternalMethod (ArgOp))
1702
                {
1703
                    return (AE_OK);
1704
                }
1705
1706
 
1707
1708
 
1709
                    RequiredBtypes, ThisNodeBtype);
1710
            }
1711
1712
 
1713
             * Now check if the actual type(s) match at least one
1714
             * bit to the required type
1715
             */
1716
            else if (!CommonBtypes)
1717
            {
1718
                /* No match -- this is a type mismatch error */
1719
1720
 
1721
                AnFormatBtype (StringBuffer2, RequiredBtypes);
1722
1723
 
1724
                            StringBuffer, OpInfo->Name, StringBuffer2);
1725
1726
 
1727
            }
1728
1729
 
1730
            ArgOp = ArgOp->Asl.Next;
1731
            INCREMENT_ARG_LIST (RuntimeArgTypes2);
1732
        }
1733
        break;
1734
1735
 
1736
        break;
1737
    }
1738
1739
 
1740
}
1741
1742
 
1743
 
1744
 *
1745
 * FUNCTION:    AnIsResultUsed
1746
 *
1747
 * PARAMETERS:  Op              - Parent op for the operator
1748
 *
1749
 * RETURN:      TRUE if result from this operation is actually consumed
1750
 *
1751
 * DESCRIPTION: Determine if the function result value from an operator is
1752
 *              used.
1753
 *
1754
 ******************************************************************************/
1755
1756
 
1757
AnIsResultUsed (
1758
    ACPI_PARSE_OBJECT       *Op)
1759
{
1760
    ACPI_PARSE_OBJECT       *Parent;
1761
1762
 
1763
 
1764
    {
1765
    case PARSEOP_INCREMENT:
1766
    case PARSEOP_DECREMENT:
1767
1768
 
1769
1770
 
1771
1772
 
1773
        break;
1774
    }
1775
1776
 
1777
1778
 
1779
    switch (Parent->Asl.ParseOpcode)
1780
    {
1781
    /* If/While - check if the operator is the predicate */
1782
1783
 
1784
    case PARSEOP_WHILE:
1785
1786
 
1787
1788
 
1789
        {
1790
            return (TRUE);
1791
        }
1792
        return (FALSE);
1793
1794
 
1795
1796
 
1797
    case PARSEOP_DEFINITIONBLOCK:
1798
    case PARSEOP_ELSE:
1799
1800
 
1801
1802
 
1803
        /* Any other type of parent means that the result is used */
1804
1805
 
1806
    }
1807
}
1808
1809
 
1810
 
1811
 *
1812
 * FUNCTION:    AnOtherSemanticAnalysisWalkBegin
1813
 *
1814
 * PARAMETERS:  ASL_WALK_CALLBACK
1815
 *
1816
 * RETURN:      Status
1817
 *
1818
 * DESCRIPTION: Descending callback for the analysis walk. Checks for
1819
 *              miscellaneous issues in the code.
1820
 *
1821
 ******************************************************************************/
1822
1823
 
1824
AnOtherSemanticAnalysisWalkBegin (
1825
    ACPI_PARSE_OBJECT       *Op,
1826
    UINT32                  Level,
1827
    void                    *Context)
1828
{
1829
    ACPI_PARSE_OBJECT       *ArgNode;
1830
    ACPI_PARSE_OBJECT       *PrevArgNode = NULL;
1831
    const ACPI_OPCODE_INFO  *OpInfo;
1832
1833
 
1834
 
1835
1836
 
1837
     * Determine if an execution class operator actually does something by
1838
     * checking if it has a target and/or the function return value is used.
1839
     * (Target is optional, so a standalone statement can actually do nothing.)
1840
     */
1841
    if ((OpInfo->Class == AML_CLASS_EXECUTE) &&
1842
        (OpInfo->Flags & AML_HAS_RETVAL) &&
1843
        (!AnIsResultUsed (Op)))
1844
    {
1845
        if (OpInfo->Flags & AML_HAS_TARGET)
1846
        {
1847
            /*
1848
             * Find the target node, it is always the last child. If the traget
1849
             * is not specified in the ASL, a default node of type Zero was
1850
             * created by the parser.
1851
             */
1852
            ArgNode = Op->Asl.Child;
1853
            while (ArgNode->Asl.Next)
1854
            {
1855
                PrevArgNode = ArgNode;
1856
                ArgNode = ArgNode->Asl.Next;
1857
            }
1858
1859
 
1860
1861
 
1862
            {
1863
                if ((ArgNode->Asl.ParseOpcode == PARSEOP_ZERO) &&
1864
                    (PrevArgNode->Asl.ParseOpcode == PARSEOP_ZERO))
1865
                {
1866
                    AslError (ASL_WARNING, ASL_MSG_RESULT_NOT_USED, Op, Op->Asl.ExternalName);
1867
                }
1868
            }
1869
            else if (ArgNode->Asl.ParseOpcode == PARSEOP_ZERO)
1870
            {
1871
                AslError (ASL_WARNING, ASL_MSG_RESULT_NOT_USED, Op, Op->Asl.ExternalName);
1872
            }
1873
        }
1874
        else
1875
        {
1876
            /*
1877
             * Has no target and the result is not used. Only a couple opcodes
1878
             * can have this combination.
1879
             */
1880
            switch (Op->Asl.ParseOpcode)
1881
            {
1882
            case PARSEOP_ACQUIRE:
1883
            case PARSEOP_WAIT:
1884
            case PARSEOP_LOADTABLE:
1885
                break;
1886
1887
 
1888
                AslError (ASL_WARNING, ASL_MSG_RESULT_NOT_USED, Op, Op->Asl.ExternalName);
1889
                break;
1890
            }
1891
        }
1892
    }
1893
1894
 
1895
 
1896
     * Semantic checks for individual ASL operators
1897
     */
1898
    switch (Op->Asl.ParseOpcode)
1899
    {
1900
    case PARSEOP_ACQUIRE:
1901
    case PARSEOP_WAIT:
1902
        /*
1903
         * Emit a warning if the timeout parameter for these operators is not
1904
         * ACPI_WAIT_FOREVER, and the result value from the operator is not
1905
         * checked, meaning that a timeout could happen, but the code
1906
         * would not know about it.
1907
         */
1908
1909
 
1910
1911
 
1912
        ArgNode = ArgNode->Asl.Next;
1913
1914
 
1915
         * Check for the WAIT_FOREVER case - defined by the ACPI spec to be
1916
         * 0xFFFF or greater
1917
         */
1918
        if (((ArgNode->Asl.ParseOpcode == PARSEOP_WORDCONST) ||
1919
             (ArgNode->Asl.ParseOpcode == PARSEOP_INTEGER))  &&
1920
             (ArgNode->Asl.Value.Integer >= (UINT64) ACPI_WAIT_FOREVER))
1921
        {
1922
            break;
1923
        }
1924
1925
 
1926
         * The operation could timeout. If the return value is not used
1927
         * (indicates timeout occurred), issue a warning
1928
         */
1929
        if (!AnIsResultUsed (Op))
1930
        {
1931
            AslError (ASL_WARNING, ASL_MSG_TIMEOUT, ArgNode, Op->Asl.ExternalName);
1932
        }
1933
        break;
1934
1935
 
1936
        /*
1937
         * Check for a zero Length (NumBits) operand. NumBits is the 3rd operand
1938
         */
1939
        ArgNode = Op->Asl.Child;
1940
        ArgNode = ArgNode->Asl.Next;
1941
        ArgNode = ArgNode->Asl.Next;
1942
1943
 
1944
           ((ArgNode->Asl.ParseOpcode == PARSEOP_INTEGER) &&
1945
            (ArgNode->Asl.Value.Integer == 0)))
1946
        {
1947
            AslError (ASL_ERROR, ASL_MSG_NON_ZERO, ArgNode, NULL);
1948
        }
1949
        break;
1950
1951
 
1952
        break;
1953
    }
1954
1955
 
1956
}
1957
1958
 
1959
 
1960
 *
1961
 * FUNCTION:    AnOtherSemanticAnalysisWalkEnd
1962
 *
1963
 * PARAMETERS:  ASL_WALK_CALLBACK
1964
 *
1965
 * RETURN:      Status
1966
 *
1967
 * DESCRIPTION: Ascending callback for analysis walk. Complete method
1968
 *              return analysis.
1969
 *
1970
 ******************************************************************************/
1971
1972
 
1973
AnOtherSemanticAnalysisWalkEnd (
1974
    ACPI_PARSE_OBJECT       *Op,
1975
    UINT32                  Level,
1976
    void                    *Context)
1977
{
1978
1979
 
1980
1981
 
1982
1983
 
1984
 
1985
/*******************************************************************************
1986
 *
1987
 * FUNCTION:    AnMapBtypeToEtype
1988
 *
1989
 * PARAMETERS:  Btype               - Bitfield of ACPI types
1990
 *
1991
 * RETURN:      The Etype corresponding the the Btype
1992
 *
1993
 * DESCRIPTION: Convert a bitfield type to an encoded type
1994
 *
1995
 ******************************************************************************/
1996
1997
 
1998
AnMapBtypeToEtype (
1999
    UINT32              Btype)
2000
{
2001
    UINT32              i;
2002
    UINT32              Etype;
2003
2004
 
2005
 
2006
    {
2007
        return 0;
2008
    }
2009
2010
 
2011
    for (i = 1; i < Btype; i *= 2)
2012
    {
2013
        Etype++;
2014
    }
2015
2016
 
2017
}
2018
#endif
2019