Update ACPI build wrappers to use new ACPICA(20050309) code.
[dragonfly.git] / sys / contrib / dev / acpica-unix-20050211 / compiler / aslanalyze.c
1
2 /******************************************************************************
3  *
4  * Module Name: aslanalyze.c - check for semantic errors
5  *              $Revision: 87 $
6  *
7  *****************************************************************************/
8
9 /******************************************************************************
10  *
11  * 1. Copyright Notice
12  *
13  * Some or all of this work - Copyright (c) 1999 - 2005, Intel Corp.
14  * All rights reserved.
15  *
16  * 2. License
17  *
18  * 2.1. This is your license from Intel Corp. under its intellectual property
19  * rights.  You may have additional license terms from the party that provided
20  * you this software, covering your right to use that party's intellectual
21  * property rights.
22  *
23  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
24  * copy of the source code appearing in this file ("Covered Code") an
25  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
26  * base code distributed originally by Intel ("Original Intel Code") to copy,
27  * make derivatives, distribute, use and display any portion of the Covered
28  * Code in any form, with the right to sublicense such rights; and
29  *
30  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
31  * license (with the right to sublicense), under only those claims of Intel
32  * patents that are infringed by the Original Intel Code, to make, use, sell,
33  * offer to sell, and import the Covered Code and derivative works thereof
34  * solely to the minimum extent necessary to exercise the above copyright
35  * license, and in no event shall the patent license extend to any additions
36  * to or modifications of the Original Intel Code.  No other license or right
37  * is granted directly or by implication, estoppel or otherwise;
38  *
39  * The above copyright and patent license is granted only if the following
40  * conditions are met:
41  *
42  * 3. Conditions
43  *
44  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
45  * Redistribution of source code of any substantial portion of the Covered
46  * Code or modification with rights to further distribute source must include
47  * the above Copyright Notice, the above License, this list of Conditions,
48  * and the following Disclaimer and Export Compliance provision.  In addition,
49  * Licensee must cause all Covered Code to which Licensee contributes to
50  * contain a file documenting the changes Licensee made to create that Covered
51  * Code and the date of any change.  Licensee must include in that file the
52  * documentation of any changes made by any predecessor Licensee.  Licensee
53  * must include a prominent statement that the modification is derived,
54  * directly or indirectly, from Original Intel Code.
55  *
56  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
57  * Redistribution of source code of any substantial portion of the Covered
58  * Code or modification without rights to further distribute source must
59  * include the following Disclaimer and Export Compliance provision in the
60  * documentation and/or other materials provided with distribution.  In
61  * addition, Licensee may not authorize further sublicense of source of any
62  * portion of the Covered Code, and must include terms to the effect that the
63  * license from Licensee to its licensee is limited to the intellectual
64  * property embodied in the software Licensee provides to its licensee, and
65  * not to intellectual property embodied in modifications its licensee may
66  * make.
67  *
68  * 3.3. Redistribution of Executable. Redistribution in executable form of any
69  * substantial portion of the Covered Code or modification must reproduce the
70  * above Copyright Notice, and the following Disclaimer and Export Compliance
71  * provision in the documentation and/or other materials provided with the
72  * distribution.
73  *
74  * 3.4. Intel retains all right, title, and interest in and to the Original
75  * Intel Code.
76  *
77  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
78  * Intel shall be used in advertising or otherwise to promote the sale, use or
79  * other dealings in products derived from or relating to the Covered Code
80  * without prior written authorization from Intel.
81  *
82  * 4. Disclaimer and Export Compliance
83  *
84  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
85  * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
86  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
87  * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
88  * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
89  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
90  * PARTICULAR PURPOSE.
91  *
92  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
93  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
94  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
95  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
96  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
97  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
98  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
99  * LIMITED REMEDY.
100  *
101  * 4.3. Licensee shall not export, either directly or indirectly, any of this
102  * software or system incorporating such software without first obtaining any
103  * required license or other approval from the U. S. Department of Commerce or
104  * any other agency or department of the United States Government.  In the
105  * event Licensee exports any such software from the United States or
106  * re-exports any such software from a foreign destination, Licensee shall
107  * ensure that the distribution and export/re-export of the software is in
108  * compliance with all laws, regulations, orders, or other restrictions of the
109  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
110  * any of its subsidiaries will export/re-export any technical data, process,
111  * software, or service, directly or indirectly, to any country for which the
112  * United States government or any agency thereof requires an export license,
113  * other governmental approval, or letter of assurance, without first obtaining
114  * such license, approval or letter.
115  *
116  *****************************************************************************/
117
118
119 #include "aslcompiler.h"
120 #include "aslcompiler.y.h"
121 #include "acparser.h"
122 #include "amlcode.h"
123
124 #include <ctype.h>
125
126 #define _COMPONENT          ACPI_COMPILER
127         ACPI_MODULE_NAME    ("aslanalyze")
128
129
130 /*******************************************************************************
131  *
132  * FUNCTION:    AnMapArgTypeToBtype
133  *
134  * PARAMETERS:  ArgType      - The ARGI required type(s) for this argument,
135  *                             from the opcode info table
136  *
137  * RETURN:      The corresponding Bit-encoded types
138  *
139  * DESCRIPTION: Convert an encoded ARGI required argument type code into a
140  *              bitfield type code.  Implements the implicit source conversion
141  *              rules.
142  *
143  ******************************************************************************/
144
145 UINT32
146 AnMapArgTypeToBtype (
147     UINT32                  ArgType)
148 {
149
150     switch (ArgType)
151     {
152
153     /* Simple types */
154
155     case ARGI_ANYTYPE:
156         return (ACPI_BTYPE_OBJECTS_AND_REFS);
157
158     case ARGI_PACKAGE:
159         return (ACPI_BTYPE_PACKAGE);
160
161     case ARGI_EVENT:
162         return (ACPI_BTYPE_EVENT);
163
164     case ARGI_MUTEX:
165         return (ACPI_BTYPE_MUTEX);
166
167     case ARGI_DDBHANDLE:
168         return (ACPI_BTYPE_DDB_HANDLE);
169
170     /* Interchangeable types */
171     /*
172      * Source conversion rules:
173      * Integer, String, and Buffer are all interchangeable
174      */
175     case ARGI_INTEGER:
176     case ARGI_STRING:
177     case ARGI_BUFFER:
178     case ARGI_BUFFER_OR_STRING:
179     case ARGI_COMPUTEDATA:
180         return (ACPI_BTYPE_COMPUTE_DATA);
181
182     /* References */
183
184     case ARGI_INTEGER_REF:
185         return (ACPI_BTYPE_INTEGER);
186
187     case ARGI_OBJECT_REF:
188         return (ACPI_BTYPE_ALL_OBJECTS);
189
190     case ARGI_DEVICE_REF:
191         return (ACPI_BTYPE_DEVICE_OBJECTS);
192
193     case ARGI_REFERENCE:
194         return (ACPI_BTYPE_REFERENCE);
195
196     case ARGI_TARGETREF:
197     case ARGI_FIXED_TARGET:
198     case ARGI_SIMPLE_TARGET:
199         return (ACPI_BTYPE_OBJECTS_AND_REFS);
200
201     /* Complex types */
202
203     case ARGI_DATAOBJECT:
204
205         /* Buffer, string, package or reference to a Op - Used only by SizeOf operator*/
206
207         return (ACPI_BTYPE_STRING | ACPI_BTYPE_BUFFER |
208             ACPI_BTYPE_PACKAGE | ACPI_BTYPE_REFERENCE);
209
210     case ARGI_COMPLEXOBJ:
211
212         /* Buffer, String, or package */
213
214         return (ACPI_BTYPE_STRING | ACPI_BTYPE_BUFFER | ACPI_BTYPE_PACKAGE);
215
216     case ARGI_REF_OR_STRING:
217         return (ACPI_BTYPE_STRING | ACPI_BTYPE_REFERENCE);
218
219     case ARGI_REGION_OR_FIELD:
220         return (ACPI_BTYPE_REGION | ACPI_BTYPE_FIELD_UNIT);
221
222     case ARGI_DATAREFOBJ:
223         return (ACPI_BTYPE_INTEGER |ACPI_BTYPE_STRING | ACPI_BTYPE_BUFFER |
224             ACPI_BTYPE_PACKAGE | ACPI_BTYPE_REFERENCE | ACPI_BTYPE_DDB_HANDLE);
225
226     default:
227         break;
228     }
229
230     return (ACPI_BTYPE_OBJECTS_AND_REFS);
231 }
232
233
234 /*******************************************************************************
235  *
236  * FUNCTION:    AnMapEtypeToBtype
237  *
238  * PARAMETERS:  Etype           - Encoded ACPI Type
239  *
240  * RETURN:      Btype corresponding to the Etype
241  *
242  * DESCRIPTION: Convert an encoded ACPI type to a bitfield type applying the
243  *              operand conversion rules.  In other words, returns the type(s)
244  *              this Etype is implicitly converted to during interpretation.
245  *
246  ******************************************************************************/
247
248 UINT32
249 AnMapEtypeToBtype (
250     UINT32              Etype)
251 {
252
253
254     if (Etype == ACPI_TYPE_ANY)
255     {
256         return ACPI_BTYPE_OBJECTS_AND_REFS;
257     }
258
259     /* Try the standard ACPI data types */
260
261     if (Etype <= ACPI_TYPE_EXTERNAL_MAX)
262     {
263         /*
264          * This switch statement implements the allowed operand conversion
265          * rules as per the "ASL Data Types" section of the ACPI
266          * specification.
267          */
268         switch (Etype)
269         {
270         case ACPI_TYPE_INTEGER:
271             return (ACPI_BTYPE_COMPUTE_DATA | ACPI_BTYPE_DDB_HANDLE);
272
273         case ACPI_TYPE_STRING:
274         case ACPI_TYPE_BUFFER:
275             return (ACPI_BTYPE_COMPUTE_DATA);
276
277         case ACPI_TYPE_PACKAGE:
278             return (ACPI_BTYPE_PACKAGE);
279
280         case ACPI_TYPE_FIELD_UNIT:
281             return (ACPI_BTYPE_COMPUTE_DATA | ACPI_BTYPE_FIELD_UNIT);
282
283         case ACPI_TYPE_BUFFER_FIELD:
284             return (ACPI_BTYPE_COMPUTE_DATA | ACPI_BTYPE_BUFFER_FIELD);
285
286         case ACPI_TYPE_DDB_HANDLE:
287             return (ACPI_BTYPE_INTEGER | ACPI_BTYPE_DDB_HANDLE);
288
289         case ACPI_BTYPE_DEBUG_OBJECT:
290
291             /* Cannot be used as a source operand */
292
293             return (0);
294
295         default:
296             return (1 << (Etype - 1));
297         }
298     }
299
300     /* Try the internal data types */
301
302     switch (Etype)
303     {
304     case ACPI_TYPE_LOCAL_REGION_FIELD:
305     case ACPI_TYPE_LOCAL_BANK_FIELD:
306     case ACPI_TYPE_LOCAL_INDEX_FIELD:
307
308         /* Named fields can be either Integer/Buffer/String */
309
310         return (ACPI_BTYPE_COMPUTE_DATA | ACPI_BTYPE_FIELD_UNIT);
311
312     case ACPI_TYPE_LOCAL_ALIAS:
313
314         return (ACPI_BTYPE_INTEGER);
315
316
317     case ACPI_TYPE_LOCAL_RESOURCE:
318     case ACPI_TYPE_LOCAL_RESOURCE_FIELD:
319
320         return (ACPI_BTYPE_REFERENCE);
321
322     default:
323         printf ("Unhandled encoded type: %X\n", Etype);
324         return (0);
325     }
326 }
327
328
329 /*******************************************************************************
330  *
331  * FUNCTION:    AnMapBtypeToEtype
332  *
333  * PARAMETERS:  Btype               - Bitfield of ACPI types
334  *
335  * RETURN:      The Etype corresponding the the Btype
336  *
337  * DESCRIPTION: Convert a bitfield type to an encoded type
338  *
339  ******************************************************************************/
340
341 UINT32
342 AnMapBtypeToEtype (
343     UINT32              Btype)
344 {
345     UINT32              i;
346     UINT32              Etype;
347
348
349     if (Btype == 0)
350     {
351         return 0;
352     }
353
354     Etype = 1;
355     for (i = 1; i < Btype; i *= 2)
356     {
357         Etype++;
358     }
359
360     return (Etype);
361 }
362
363
364 /*******************************************************************************
365  *
366  * FUNCTION:    AnFormatBtype
367  *
368  * PARAMETERS:  Btype               - Bitfield of ACPI types
369  *              Buffer              - Where to put the ascii string
370  *
371  * RETURN:      None.
372  *
373  * DESCRIPTION: Convert a Btype to a string of ACPI types
374  *
375  ******************************************************************************/
376
377 void
378 AnFormatBtype (
379     char                *Buffer,
380     UINT32              Btype)
381 {
382     UINT32              Type;
383     BOOLEAN             First = TRUE;
384
385
386     *Buffer = 0;
387
388     if (Btype == 0)
389     {
390         strcat (Buffer, "NoReturnValue");
391         return;
392     }
393
394     for (Type = 1; Type <= ACPI_TYPE_EXTERNAL_MAX; Type++)
395     {
396         if (Btype & 0x00000001)
397         {
398             if (!First)
399             {
400                 strcat (Buffer, "|");
401             }
402             First = FALSE;
403             strcat (Buffer, AcpiUtGetTypeName (Type));
404         }
405         Btype >>= 1;
406     }
407
408     if (Btype & 0x00000001)
409     {
410         if (!First)
411         {
412             strcat (Buffer, "|");
413         }
414         First = FALSE;
415         strcat (Buffer, "Reference");
416     }
417
418     Btype >>= 1;
419     if (Btype & 0x00000001)
420     {
421         if (!First)
422         {
423             strcat (Buffer, "|");
424         }
425         First = FALSE;
426         strcat (Buffer, "Resource");
427     }
428 }
429
430
431 /*******************************************************************************
432  *
433  * FUNCTION:    AnGetBtype
434  *
435  * PARAMETERS:  Op          - Parse node whose type will be returned.
436  *
437  * RETURN:      The Btype associated with the Op.
438  *
439  * DESCRIPTION: Get the (bitfield) ACPI type associated with the parse node.
440  *              Handles the case where the node is a name or method call and
441  *              the actual type must be obtained from the namespace node.
442  *
443  ******************************************************************************/
444
445 UINT32
446 AnGetBtype (
447     ACPI_PARSE_OBJECT       *Op)
448 {
449     ACPI_NAMESPACE_NODE     *Node;
450     ACPI_PARSE_OBJECT       *ReferencedNode;
451     UINT32                  ThisNodeBtype = 0;
452
453
454     if ((Op->Asl.ParseOpcode == PARSEOP_NAMESEG)     ||
455         (Op->Asl.ParseOpcode == PARSEOP_NAMESTRING)  ||
456         (Op->Asl.ParseOpcode == PARSEOP_METHODCALL))
457     {
458         Node = Op->Asl.Node;
459         if (!Node)
460         {
461             DbgPrint (ASL_DEBUG_OUTPUT,
462                 "No attached Nsnode: [%s] at line %d name [%s], ignoring typecheck\n",
463                 Op->Asl.ParseOpName, Op->Asl.LineNumber,
464                 Op->Asl.ExternalName);
465             return ACPI_UINT32_MAX;
466         }
467
468         ThisNodeBtype = AnMapEtypeToBtype (Node->Type);
469
470         /*
471          * Since it was a named reference, enable the
472          * reference bit also
473          */
474         ThisNodeBtype |= ACPI_BTYPE_REFERENCE;
475
476         if (Op->Asl.ParseOpcode == PARSEOP_METHODCALL)
477         {
478             ReferencedNode = ACPI_CAST_PTR (ACPI_PARSE_OBJECT, Node->Object);
479             if (!ReferencedNode)
480             {
481                printf ("No back ptr to Op: type %X\n", Node->Type);
482                return ACPI_UINT32_MAX;
483             }
484
485             if (ReferencedNode->Asl.CompileFlags & NODE_METHOD_TYPED)
486             {
487                 ThisNodeBtype = ReferencedNode->Asl.AcpiBtype;
488             }
489             else
490             {
491                 return (ACPI_UINT32_MAX -1);
492             }
493         }
494     }
495     else
496     {
497         ThisNodeBtype = Op->Asl.AcpiBtype;
498     }
499
500     return (ThisNodeBtype);
501 }
502
503
504 /*******************************************************************************
505  *
506  * FUNCTION:    AnCheckForReservedName
507  *
508  * PARAMETERS:  Op              - A parse node
509  *              Name            - NameSeg to check
510  *
511  * RETURN:      None
512  *
513  * DESCRIPTION: Check a NameSeg against the reserved list.
514  *
515  ******************************************************************************/
516
517 #define ACPI_VALID_RESERVED_NAME_MAX    0x80000000
518 #define ACPI_NOT_RESERVED_NAME          ACPI_UINT32_MAX
519 #define ACPI_PREDEFINED_NAME            (ACPI_UINT32_MAX - 1)
520 #define ACPI_EVENT_RESERVED_NAME        (ACPI_UINT32_MAX - 2)
521 #define ACPI_COMPILER_RESERVED_NAME     (ACPI_UINT32_MAX - 3)
522
523 UINT32
524 AnCheckForReservedName (
525     ACPI_PARSE_OBJECT       *Op,
526     char                    *Name)
527 {
528     UINT32                  i;
529
530
531     if (Name[0] == 0)
532     {
533         AcpiOsPrintf ("Found a null name, external = %s\n", Op->Asl.ExternalName);
534     }
535
536     /* All reserved names are prefixed with a single underscore */
537
538     if (Name[0] != '_')
539     {
540         return (ACPI_NOT_RESERVED_NAME);
541     }
542
543     /* Check for a standard reserved method name */
544
545     for (i = 0; ReservedMethods[i].Name; i++)
546     {
547         if (!ACPI_STRNCMP (Name, ReservedMethods[i].Name, ACPI_NAME_SIZE))
548         {
549             if (ReservedMethods[i].Flags & ASL_RSVD_SCOPE)
550             {
551                 AslError (ASL_ERROR, ASL_MSG_RESERVED_WORD, Op, Op->Asl.ExternalName);
552                 return (ACPI_PREDEFINED_NAME);
553             }
554             else if (ReservedMethods[i].Flags & ASL_RSVD_RESOURCE_NAME)
555             {
556                 AslError (ASL_ERROR, ASL_MSG_RESERVED_WORD, Op, Op->Asl.ExternalName);
557                 return (ACPI_PREDEFINED_NAME);
558             }
559
560             /* Return index into reserved array */
561
562             return i;
563         }
564     }
565
566     /*
567      * Now check for the "special" reserved names --
568      * GPE:  _Lxx
569      * GPE:  _Exx
570      * EC:   _Qxx
571      */
572     if ((Name[1] == 'L') ||
573         (Name[1] == 'E') ||
574         (Name[1] == 'Q'))
575     {
576         /* The next two characters must be hex digits */
577
578         if ((isxdigit (Name[2])) &&
579             (isxdigit (Name[3])))
580         {
581             return (ACPI_EVENT_RESERVED_NAME);
582         }
583     }
584
585
586     /* Check for the names reserved for the compiler itself: _T_x */
587
588     else if ((Op->Asl.ExternalName[1] == 'T') &&
589              (Op->Asl.ExternalName[2] == '_'))
590     {
591         /* Ignore if actually emitted by the compiler */
592
593         if (Op->Asl.CompileFlags & NODE_COMPILER_EMITTED)
594         {
595             return (ACPI_NOT_RESERVED_NAME);
596         }
597
598         AslError (ASL_ERROR, ASL_MSG_RESERVED_WORD, Op, Op->Asl.ExternalName);
599         return (ACPI_COMPILER_RESERVED_NAME);
600     }
601
602     /*
603      * The name didn't match any of the known reserved names.  Flag it as a
604      * warning, since the entire namespace starting with an underscore is
605      * reserved by the ACPI spec.
606      */
607     AslError (ASL_WARNING, ASL_MSG_UNKNOWN_RESERVED_NAME, Op, Op->Asl.ExternalName);
608
609     return (ACPI_NOT_RESERVED_NAME);
610 }
611
612
613 /*******************************************************************************
614  *
615  * FUNCTION:    AnCheckForReservedMethod
616  *
617  * PARAMETERS:  Op              - A parse node of type "METHOD".
618  *              MethodInfo      - Saved info about this method
619  *
620  * RETURN:      None
621  *
622  * DESCRIPTION: If method is a reserved name, check that the number of arguments
623  *              and the return type (returns a value or not) is correct.
624  *
625  ******************************************************************************/
626
627 void
628 AnCheckForReservedMethod (
629     ACPI_PARSE_OBJECT       *Op,
630     ASL_METHOD_INFO         *MethodInfo)
631 {
632     UINT32                  Index;
633
634
635     /* Check for a match against the reserved name list */
636
637     Index = AnCheckForReservedName (Op, Op->Asl.NameSeg);
638
639     switch (Index)
640     {
641     case ACPI_NOT_RESERVED_NAME:
642     case ACPI_PREDEFINED_NAME:
643     case ACPI_COMPILER_RESERVED_NAME:
644
645         /* Just return, nothing to do */
646         break;
647
648
649     case ACPI_EVENT_RESERVED_NAME:
650
651         Gbl_ReservedMethods++;
652
653         /* NumArguments must be zero for all _Lxx, _Exx, and _Qxx methods */
654
655         if (MethodInfo->NumArguments != 0)
656         {
657             sprintf (MsgBuffer, " %s requires %d",
658                         Op->Asl.ExternalName, 0);
659
660             AslError (ASL_WARNING, ASL_MSG_RESERVED_ARG_COUNT_HI, Op, MsgBuffer);
661         }
662         break;
663
664
665     default:
666
667         Gbl_ReservedMethods++;
668
669         /* Matched a reserved method name */
670
671         if (MethodInfo->NumArguments != ReservedMethods[Index].NumArguments)
672         {
673             sprintf (MsgBuffer, " %s requires %d",
674                         ReservedMethods[Index].Name,
675                         ReservedMethods[Index].NumArguments);
676
677             if (MethodInfo->NumArguments > ReservedMethods[Index].NumArguments)
678             {
679                 AslError (ASL_WARNING, ASL_MSG_RESERVED_ARG_COUNT_HI, Op, MsgBuffer);
680             }
681             else
682             {
683                 AslError (ASL_WARNING, ASL_MSG_RESERVED_ARG_COUNT_LO, Op, MsgBuffer);
684             }
685         }
686
687         if (MethodInfo->NumReturnNoValue &&
688             ReservedMethods[Index].Flags & ASL_RSVD_RETURN_VALUE)
689         {
690             sprintf (MsgBuffer, "%s", ReservedMethods[Index].Name);
691
692             AslError (ASL_WARNING, ASL_MSG_RESERVED_RETURN_VALUE, Op, MsgBuffer);
693         }
694         break;
695     }
696 }
697
698
699 UINT32
700 AnMapObjTypeToBtype (
701     ACPI_PARSE_OBJECT       *Op)
702 {
703
704     switch (Op->Asl.ParseOpcode)
705     {
706     case PARSEOP_OBJECTTYPE_BFF:        /* "BuffFieldObj" */
707         return (ACPI_BTYPE_BUFFER_FIELD);
708
709     case PARSEOP_OBJECTTYPE_BUF:        /* "BuffObj" */
710         return (ACPI_BTYPE_BUFFER);
711
712     case PARSEOP_OBJECTTYPE_DDB:        /* "DDBHandleObj" */
713         return (ACPI_BTYPE_DDB_HANDLE);
714
715     case PARSEOP_OBJECTTYPE_DEV:        /* "DeviceObj" */
716         return (ACPI_BTYPE_DEVICE);
717
718     case PARSEOP_OBJECTTYPE_EVT:        /* "EventObj" */
719         return (ACPI_BTYPE_EVENT);
720
721     case PARSEOP_OBJECTTYPE_FLD:        /* "FieldUnitObj" */
722         return (ACPI_BTYPE_FIELD_UNIT);
723
724     case PARSEOP_OBJECTTYPE_INT:        /* "IntObj" */
725         return (ACPI_BTYPE_INTEGER);
726
727     case PARSEOP_OBJECTTYPE_MTH:        /* "MethodObj" */
728         return (ACPI_BTYPE_METHOD);
729
730     case PARSEOP_OBJECTTYPE_MTX:        /* "MutexObj" */
731         return (ACPI_BTYPE_MUTEX);
732
733     case PARSEOP_OBJECTTYPE_OPR:        /* "OpRegionObj" */
734         return (ACPI_BTYPE_REGION);
735
736     case PARSEOP_OBJECTTYPE_PKG:        /* "PkgObj" */
737         return (ACPI_BTYPE_PACKAGE);
738
739     case PARSEOP_OBJECTTYPE_POW:        /* "PowerResObj" */
740         return (ACPI_BTYPE_POWER);
741
742     case PARSEOP_OBJECTTYPE_STR:        /* "StrObj" */
743         return (ACPI_BTYPE_STRING);
744
745     case PARSEOP_OBJECTTYPE_THZ:        /* "ThermalZoneObj" */
746         return (ACPI_BTYPE_THERMAL);
747
748     case PARSEOP_OBJECTTYPE_UNK:        /* "UnknownObj" */
749         return (ACPI_BTYPE_OBJECTS_AND_REFS);
750
751     default:
752         return (0);
753     }
754 }
755
756
757 /*******************************************************************************
758  *
759  * FUNCTION:    AnMethodAnalysisWalkBegin
760  *
761  * PARAMETERS:  ASL_WALK_CALLBACK
762  *
763  * RETURN:      Status
764  *
765  * DESCRIPTION: Descending callback for the analysis walk.  Check methods for :
766  *              1) Initialized local variables
767  *              2) Valid arguments
768  *              3) Return types
769  *
770  ******************************************************************************/
771
772 ACPI_STATUS
773 AnMethodAnalysisWalkBegin (
774     ACPI_PARSE_OBJECT       *Op,
775     UINT32                  Level,
776     void                    *Context)
777 {
778     ASL_ANALYSIS_WALK_INFO  *WalkInfo = (ASL_ANALYSIS_WALK_INFO *) Context;
779     ASL_METHOD_INFO         *MethodInfo = WalkInfo->MethodStack;
780     ACPI_PARSE_OBJECT       *Next;
781     UINT32                  RegisterNumber;
782     UINT32                  i;
783     char                    LocalName[] = "Local0";
784     char                    ArgName[] = "Arg0";
785     ACPI_PARSE_OBJECT       *ArgNode;
786     ACPI_PARSE_OBJECT       *NextType;
787     ACPI_PARSE_OBJECT       *NextParamType;
788     char                    ActualArgs = 0;
789
790
791     ACPI_FUNCTION_NAME ("AnMethodAnalysisWalkBegin");
792
793
794     switch (Op->Asl.ParseOpcode)
795     {
796     case PARSEOP_METHOD:
797
798         TotalMethods++;
799
800         /*
801          * Create and init method info
802          */
803         MethodInfo       = UtLocalCalloc (sizeof (ASL_METHOD_INFO));
804         MethodInfo->Next = WalkInfo->MethodStack;
805         MethodInfo->Op = Op;
806
807         WalkInfo->MethodStack = MethodInfo;
808
809         /* Get the name node, ignored here */
810
811         Next = Op->Asl.Child;
812
813         /* Get the NumArguments node */
814
815         Next = Next->Asl.Next;
816         MethodInfo->NumArguments = (UINT8) (((UINT8) Next->Asl.Value.Integer) & 0x07);
817
818         /* Get the SerializeRule and SyncLevel nodes, ignored here */
819
820         Next = Next->Asl.Next;
821         Next = Next->Asl.Next;
822         ArgNode = Next;
823
824         /* Get the ReturnType node */
825
826         Next = Next->Asl.Next;
827
828         NextType = Next->Asl.Child;
829         while (NextType)
830         {
831             /* Get and map each of the ReturnTypes */
832
833             MethodInfo->ValidReturnTypes |= AnMapObjTypeToBtype (NextType);
834             NextType->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
835             NextType = NextType->Asl.Next;
836         }
837
838         /* Get the ParameterType node */
839
840         Next = Next->Asl.Next;
841
842         NextType = Next->Asl.Child;
843         while (NextType)
844         {
845             if (NextType->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG)
846             {
847                 NextParamType = NextType->Asl.Child;
848                 while (NextParamType)
849                 {
850                     MethodInfo->ValidArgTypes[ActualArgs] |= AnMapObjTypeToBtype (NextParamType);
851                     NextParamType->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
852                     NextParamType = NextParamType->Asl.Next;
853                 }
854             }
855             else
856             {
857                 MethodInfo->ValidArgTypes[ActualArgs] = AnMapObjTypeToBtype (NextType);
858                 NextType->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
859             }
860
861             ActualArgs++;
862             NextType = NextType->Asl.Next;
863         }
864
865         if ((MethodInfo->NumArguments) &&
866             (MethodInfo->NumArguments != ActualArgs))
867         {
868             /* error: Param list did not match number of args */
869         }
870
871         /* Allow numarguments == 0 for Function() */
872
873         if ((!MethodInfo->NumArguments) && (ActualArgs))
874         {
875             MethodInfo->NumArguments = ActualArgs;
876             ArgNode->Asl.Value.Integer |= ActualArgs;
877         }
878
879         /*
880          * Actual arguments are initialized at method entry.
881          * All other ArgX "registers" can be used as locals, so we
882          * track their initialization.
883          */
884         for (i = 0; i < MethodInfo->NumArguments; i++)
885         {
886             MethodInfo->ArgInitialized[i] = TRUE;
887         }
888         break;
889
890
891     case PARSEOP_METHODCALL:
892
893         if (MethodInfo &&
894            (Op->Asl.Node == MethodInfo->Op->Asl.Node))
895         {
896             AslError (ASL_REMARK, ASL_MSG_RECURSION, Op, Op->Asl.ExternalName);
897         }
898         break;
899
900
901     case PARSEOP_LOCAL0:
902     case PARSEOP_LOCAL1:
903     case PARSEOP_LOCAL2:
904     case PARSEOP_LOCAL3:
905     case PARSEOP_LOCAL4:
906     case PARSEOP_LOCAL5:
907     case PARSEOP_LOCAL6:
908     case PARSEOP_LOCAL7:
909
910         if (!MethodInfo)
911         {
912             /* Probably was an error in the method declaration, no additional error here */
913
914             ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "%p, No parent method\n", Op));
915             return (AE_ERROR);
916         }
917
918         RegisterNumber = (Op->Asl.AmlOpcode & 0x000F);
919
920         /*
921          * If the local is being used as a target, mark the local
922          * initialized
923          */
924         if (Op->Asl.CompileFlags & NODE_IS_TARGET)
925         {
926             MethodInfo->LocalInitialized[RegisterNumber] = TRUE;
927         }
928
929         /*
930          * Otherwise, this is a reference, check if the local
931          * has been previously initialized.
932          *
933          * The only operator that accepts an uninitialized value is ObjectType()
934          */
935         else if ((!MethodInfo->LocalInitialized[RegisterNumber]) &&
936                  (Op->Asl.Parent->Asl.ParseOpcode != PARSEOP_OBJECTTYPE))
937         {
938             LocalName[strlen (LocalName) -1] = (char) (RegisterNumber + 0x30);
939             AslError (ASL_ERROR, ASL_MSG_LOCAL_INIT, Op, LocalName);
940         }
941         break;
942
943
944     case PARSEOP_ARG0:
945     case PARSEOP_ARG1:
946     case PARSEOP_ARG2:
947     case PARSEOP_ARG3:
948     case PARSEOP_ARG4:
949     case PARSEOP_ARG5:
950     case PARSEOP_ARG6:
951
952         if (!MethodInfo)
953         {
954             /* Probably was an error in the method declaration, no additional error here */
955
956             ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "%p, No parent method\n", Op));
957             return (AE_ERROR);
958         }
959
960         RegisterNumber = (Op->Asl.AmlOpcode & 0x000F) - 8;
961         ArgName[strlen (ArgName) -1] = (char) (RegisterNumber + 0x30);
962
963         /*
964          * If the Arg is being used as a target, mark the local
965          * initialized
966          */
967         if (Op->Asl.CompileFlags & NODE_IS_TARGET)
968         {
969             MethodInfo->ArgInitialized[RegisterNumber] = TRUE;
970         }
971
972         /*
973          * Otherwise, this is a reference, check if the Arg
974          * has been previously initialized.
975          *
976          * The only operator that accepts an uninitialized value is ObjectType()
977          */
978         else if ((!MethodInfo->ArgInitialized[RegisterNumber]) &&
979                  (Op->Asl.Parent->Asl.ParseOpcode != PARSEOP_OBJECTTYPE))
980         {
981             AslError (ASL_ERROR, ASL_MSG_ARG_INIT, Op, ArgName);
982         }
983
984         /* Flag this arg if it is not a "real" argument to the method */
985
986         if (RegisterNumber >= MethodInfo->NumArguments)
987         {
988             AslError (ASL_REMARK, ASL_MSG_NOT_PARAMETER, Op, ArgName);
989         }
990         break;
991
992
993     case PARSEOP_RETURN:
994
995         if (!MethodInfo)
996         {
997             /* Probably was an error in the method declaration, no additional error here */
998
999             ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "%p, No parent method\n", Op));
1000             return (AE_ERROR);
1001         }
1002
1003         /* Child indicates a return value */
1004
1005         if ((Op->Asl.Child) &&
1006             (Op->Asl.Child->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG))
1007         {
1008             MethodInfo->NumReturnWithValue++;
1009         }
1010         else
1011         {
1012             MethodInfo->NumReturnNoValue++;
1013         }
1014         break;
1015
1016
1017     case PARSEOP_BREAK:
1018     case PARSEOP_CONTINUE:
1019
1020         Next = Op->Asl.Parent;
1021         while (Next)
1022         {
1023             if (Next->Asl.ParseOpcode == PARSEOP_WHILE)
1024             {
1025                 break;
1026             }
1027             Next = Next->Asl.Parent;
1028         }
1029
1030         if (!Next)
1031         {
1032             AslError (ASL_ERROR, ASL_MSG_NO_WHILE, Op, NULL);
1033         }
1034         break;
1035
1036
1037     case PARSEOP_STALL:
1038
1039         if (Op->Asl.Child->Asl.Value.Integer > ACPI_UINT8_MAX)
1040         {
1041             AslError (ASL_ERROR, ASL_MSG_INVALID_TIME, Op, NULL);
1042         }
1043         break;
1044
1045
1046     case PARSEOP_DEVICE:
1047     case PARSEOP_EVENT:
1048     case PARSEOP_MUTEX:
1049     case PARSEOP_OPERATIONREGION:
1050     case PARSEOP_POWERRESOURCE:
1051     case PARSEOP_PROCESSOR:
1052     case PARSEOP_THERMALZONE:
1053
1054         /*
1055          * The first operand is a name to be created in the namespace.
1056          * Check against the reserved list.
1057          */
1058         i = AnCheckForReservedName (Op, Op->Asl.NameSeg);
1059         if (i < ACPI_VALID_RESERVED_NAME_MAX)
1060         {
1061             AslError (ASL_ERROR, ASL_MSG_RESERVED_USE, Op, Op->Asl.ExternalName);
1062         }
1063         break;
1064
1065
1066     case PARSEOP_NAME:
1067
1068         i = AnCheckForReservedName (Op, Op->Asl.NameSeg);
1069         if (i < ACPI_VALID_RESERVED_NAME_MAX)
1070         {
1071             if (ReservedMethods[i].NumArguments > 0)
1072             {
1073                 /*
1074                  * This reserved name must be a control method because
1075                  * it must have arguments
1076                  */
1077                 AslError (ASL_ERROR, ASL_MSG_RESERVED_METHOD, Op, "with arguments");
1078             }
1079
1080             /*
1081              * Typechecking for _HID
1082              */
1083             else if (!ACPI_STRCMP (METHOD_NAME__HID, ReservedMethods[i].Name))
1084             {
1085                 /* Examine the second operand to typecheck it */
1086
1087                 Next = Op->Asl.Child->Asl.Next;
1088
1089                 if ((Next->Asl.ParseOpcode != PARSEOP_INTEGER) &&
1090                     (Next->Asl.ParseOpcode != PARSEOP_STRING_LITERAL))
1091                 {
1092                     /* _HID must be a string or an integer */
1093
1094                     AslError (ASL_ERROR, ASL_MSG_RESERVED_OPERAND_TYPE, Next, "String or Integer");
1095                 }
1096
1097                 if (Next->Asl.ParseOpcode == PARSEOP_STRING_LITERAL)
1098                 {
1099                     /*
1100                      * _HID is a string, all characters must be alphanumeric.
1101                      * One of the things we want to catch here is the use of
1102                      * a leading asterisk in the string.
1103                      */
1104                     for (i = 0; Next->Asl.Value.String[i]; i++)
1105                     {
1106                         if (!isalnum (Next->Asl.Value.String[i]))
1107                         {
1108                             AslError (ASL_ERROR, ASL_MSG_ALPHANUMERIC_STRING, Next, Next->Asl.Value.String);
1109                             break;
1110                         }
1111                     }
1112                 }
1113             }
1114         }
1115
1116         break;
1117
1118
1119     default:
1120         break;
1121     }
1122
1123     return AE_OK;
1124 }
1125
1126
1127 /*******************************************************************************
1128  *
1129  * FUNCTION:    AnLastStatementIsReturn
1130  *
1131  * PARAMETERS:  Op            - A method parse node
1132  *
1133  * RETURN:      TRUE if last statement is an ASL RETURN.  False otherwise
1134  *
1135  * DESCRIPTION: Walk down the list of top level statements within a method
1136  *              to find the last one.  Check if that last statement is in
1137  *              fact a RETURN statement.
1138  *
1139  ******************************************************************************/
1140
1141 BOOLEAN
1142 AnLastStatementIsReturn (
1143     ACPI_PARSE_OBJECT       *Op)
1144 {
1145     ACPI_PARSE_OBJECT       *Next;
1146
1147
1148     /*
1149      * Check if last statement is a return
1150      */
1151     Next = ASL_GET_CHILD_NODE (Op);
1152     while (Next)
1153     {
1154         if ((!Next->Asl.Next) &&
1155             (Next->Asl.ParseOpcode == PARSEOP_RETURN))
1156         {
1157             return TRUE;
1158         }
1159
1160         Next = ASL_GET_PEER_NODE (Next);
1161     }
1162
1163     return FALSE;
1164 }
1165
1166
1167 /*******************************************************************************
1168  *
1169  * FUNCTION:    AnMethodAnalysisWalkEnd
1170  *
1171  * PARAMETERS:  ASL_WALK_CALLBACK
1172  *
1173  * RETURN:      Status
1174  *
1175  * DESCRIPTION: Ascending callback for analysis walk.  Complete method
1176  *              return analysis.
1177  *
1178  ******************************************************************************/
1179
1180 ACPI_STATUS
1181 AnMethodAnalysisWalkEnd (
1182     ACPI_PARSE_OBJECT       *Op,
1183     UINT32                  Level,
1184     void                    *Context)
1185 {
1186     ASL_ANALYSIS_WALK_INFO  *WalkInfo = (ASL_ANALYSIS_WALK_INFO *) Context;
1187     ASL_METHOD_INFO         *MethodInfo = WalkInfo->MethodStack;
1188
1189
1190     switch (Op->Asl.ParseOpcode)
1191     {
1192     case PARSEOP_METHOD:
1193     case PARSEOP_RETURN:
1194         if (!MethodInfo)
1195         {
1196             printf ("No method info for method! [%s]\n", Op->Asl.Namepath);
1197             AslError (ASL_ERROR, ASL_MSG_COMPILER_INTERNAL, Op, "No method info for this method");
1198             CmCleanupAndExit ();
1199             return (AE_AML_INTERNAL);
1200         }
1201         break;
1202
1203     default:
1204         break;
1205     }
1206
1207     switch (Op->Asl.ParseOpcode)
1208     {
1209     case PARSEOP_METHOD:
1210
1211         WalkInfo->MethodStack = MethodInfo->Next;
1212
1213         /*
1214          * Check if there is no return statement at the end of the
1215          * method AND we can actually get there -- i.e., the execution
1216          * of the method can possibly terminate without a return statement.
1217          */
1218         if ((!AnLastStatementIsReturn (Op)) &&
1219             (!(Op->Asl.CompileFlags & NODE_HAS_NO_EXIT)))
1220         {
1221             /*
1222              * No return statement, and execution can possibly exit
1223              * via this path.  This is equivalent to Return ()
1224              */
1225             MethodInfo->NumReturnNoValue++;
1226         }
1227
1228         /*
1229          * Check for case where some return statements have a return value
1230          * and some do not.  Exit without a return statement is a return with
1231          * no value
1232          */
1233         if (MethodInfo->NumReturnNoValue &&
1234             MethodInfo->NumReturnWithValue)
1235         {
1236             AslError (ASL_WARNING, ASL_MSG_RETURN_TYPES, Op, Op->Asl.ExternalName);
1237         }
1238
1239         /*
1240          * If there are any RETURN() statements with no value, or there is a
1241          * control path that allows the method to exit without a return value,
1242          * we mark the method as a method that does not return a value.  This
1243          * knowledge can be used to check method invocations that expect a
1244          * returned value.
1245          */
1246         if (MethodInfo->NumReturnNoValue)
1247         {
1248             if (MethodInfo->NumReturnWithValue)
1249             {
1250                 Op->Asl.CompileFlags |= NODE_METHOD_SOME_NO_RETVAL;
1251             }
1252             else
1253             {
1254                 Op->Asl.CompileFlags |= NODE_METHOD_NO_RETVAL;
1255             }
1256         }
1257
1258         /*
1259          * Check predefined method names for correct return behavior
1260          * and correct number of arguments
1261          */
1262         AnCheckForReservedMethod (Op, MethodInfo);
1263         ACPI_MEM_FREE (MethodInfo);
1264         break;
1265
1266
1267     case PARSEOP_RETURN:
1268
1269         /*
1270          * The parent block does not "exit" and continue execution -- the
1271          * method is terminated here with the Return() statement.
1272          */
1273         Op->Asl.Parent->Asl.CompileFlags |= NODE_HAS_NO_EXIT;
1274         Op->Asl.ParentMethod = MethodInfo->Op;      /* Used in the "typing" pass later */
1275
1276         /*
1277          * If there is a peer node after the return statement, then this
1278          * node is unreachable code -- i.e., it won't be executed because of the
1279          * preceeding Return() statement.
1280          */
1281         if (Op->Asl.Next)
1282         {
1283             AslError (ASL_WARNING, ASL_MSG_UNREACHABLE_CODE, Op->Asl.Next, NULL);
1284         }
1285         break;
1286
1287
1288     case PARSEOP_IF:
1289
1290         if ((Op->Asl.CompileFlags & NODE_HAS_NO_EXIT) &&
1291             (Op->Asl.Next) &&
1292             (Op->Asl.Next->Asl.ParseOpcode == PARSEOP_ELSE))
1293         {
1294             /*
1295              * This IF has a corresponding ELSE.  The IF block has no exit,
1296              * (it contains an unconditional Return)
1297              * mark the ELSE block to remember this fact.
1298              */
1299             Op->Asl.Next->Asl.CompileFlags |= NODE_IF_HAS_NO_EXIT;
1300         }
1301         break;
1302
1303
1304     case PARSEOP_ELSE:
1305
1306         if ((Op->Asl.CompileFlags & NODE_HAS_NO_EXIT) &&
1307             (Op->Asl.CompileFlags & NODE_IF_HAS_NO_EXIT))
1308         {
1309             /*
1310              * This ELSE block has no exit and the corresponding IF block
1311              * has no exit either.  Therefore, the parent node has no exit.
1312              */
1313             Op->Asl.Parent->Asl.CompileFlags |= NODE_HAS_NO_EXIT;
1314         }
1315         break;
1316
1317
1318     default:
1319
1320         if ((Op->Asl.CompileFlags & NODE_HAS_NO_EXIT) &&
1321             (Op->Asl.Parent))
1322         {
1323             /* If this node has no exit, then the parent has no exit either */
1324
1325             Op->Asl.Parent->Asl.CompileFlags |= NODE_HAS_NO_EXIT;
1326         }
1327         break;
1328     }
1329
1330     return AE_OK;
1331 }
1332
1333
1334 /*******************************************************************************
1335  *
1336  * FUNCTION:    AnMethodTypingWalkBegin
1337  *
1338  * PARAMETERS:  ASL_WALK_CALLBACK
1339  *
1340  * RETURN:      Status
1341  *
1342  * DESCRIPTION: Descending callback for the typing walk.
1343  *
1344  ******************************************************************************/
1345
1346 ACPI_STATUS
1347 AnMethodTypingWalkBegin (
1348     ACPI_PARSE_OBJECT       *Op,
1349     UINT32                  Level,
1350     void                    *Context)
1351 {
1352
1353     return AE_OK;
1354 }
1355
1356
1357 /*******************************************************************************
1358  *
1359  * FUNCTION:    AnMethodTypingWalkEnd
1360  *
1361  * PARAMETERS:  ASL_WALK_CALLBACK
1362  *
1363  * RETURN:      Status
1364  *
1365  * DESCRIPTION: Ascending callback for typing walk.  Complete method
1366  *              return analysis.  Check methods for :
1367  *              1) Initialized local variables
1368  *              2) Valid arguments
1369  *              3) Return types
1370  *
1371  ******************************************************************************/
1372
1373 ACPI_STATUS
1374 AnMethodTypingWalkEnd (
1375     ACPI_PARSE_OBJECT       *Op,
1376     UINT32                  Level,
1377     void                    *Context)
1378 {
1379     UINT32                  ThisNodeBtype;
1380
1381
1382     switch (Op->Asl.ParseOpcode)
1383     {
1384     case PARSEOP_METHOD:
1385
1386         Op->Asl.CompileFlags |= NODE_METHOD_TYPED;
1387         break;
1388
1389     case PARSEOP_RETURN:
1390
1391         if ((Op->Asl.Child) &&
1392             (Op->Asl.Child->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG))
1393         {
1394             ThisNodeBtype = AnGetBtype (Op->Asl.Child);
1395
1396             if ((Op->Asl.Child->Asl.ParseOpcode == PARSEOP_METHODCALL) &&
1397                 (ThisNodeBtype == (ACPI_UINT32_MAX -1)))
1398             {
1399                 /*
1400                  * The method is untyped at this time (typically a forward reference).
1401                  * We must recursively type the method here
1402                  */
1403                 TrWalkParseTree (ACPI_CAST_PTR (ACPI_PARSE_OBJECT, Op->Asl.Child->Asl.Node->Object),
1404                         ASL_WALK_VISIT_TWICE, AnMethodTypingWalkBegin,
1405                         AnMethodTypingWalkEnd, NULL);
1406
1407                 ThisNodeBtype = AnGetBtype (Op->Asl.Child);
1408             }
1409
1410             /* Returns a value, get it's type */
1411
1412             if (Op->Asl.ParentMethod)
1413             {
1414                 Op->Asl.ParentMethod->Asl.AcpiBtype |= ThisNodeBtype;
1415             }
1416         }
1417         break;
1418
1419     default:
1420         break;
1421     }
1422
1423     return AE_OK;
1424 }
1425
1426
1427 /*******************************************************************************
1428  *
1429  * FUNCTION:    AnCheckMethodReturnValue
1430  *
1431  * PARAMETERS:  Op                  - Parent
1432  *              OpInfo              - Parent info
1433  *              ArgOp               - Method invocation op
1434  *              RequiredBtypes      - What caller requires
1435  *              ThisNodeBtype       - What this node returns (if anything)
1436  *
1437  * RETURN:      None
1438  *
1439  * DESCRIPTION: Check a method invocation for 1) A return value and if it does
1440  *              in fact return a value, 2) check the type of the return value.
1441  *
1442  ******************************************************************************/
1443
1444 void
1445 AnCheckMethodReturnValue (
1446     ACPI_PARSE_OBJECT       *Op,
1447     const ACPI_OPCODE_INFO  *OpInfo,
1448     ACPI_PARSE_OBJECT       *ArgOp,
1449     UINT32                  RequiredBtypes,
1450     UINT32                  ThisNodeBtype)
1451 {
1452     ACPI_PARSE_OBJECT       *OwningOp;
1453     ACPI_NAMESPACE_NODE     *Node;
1454
1455
1456     Node = ArgOp->Asl.Node;
1457
1458
1459     /* Examine the parent op of this method */
1460
1461     OwningOp = ACPI_CAST_PTR (ACPI_PARSE_OBJECT, Node->Object);
1462     if (OwningOp->Asl.CompileFlags & NODE_METHOD_NO_RETVAL)
1463     {
1464         /*
1465          * Method NEVER returns a value
1466          */
1467         AslError (ASL_ERROR, ASL_MSG_NO_RETVAL, Op, Op->Asl.ExternalName);
1468     }
1469     else if (OwningOp->Asl.CompileFlags & NODE_METHOD_SOME_NO_RETVAL)
1470     {
1471         /*
1472          * Method SOMETIMES returns a value, SOMETIMES not
1473          */
1474         AslError (ASL_WARNING, ASL_MSG_SOME_NO_RETVAL, Op, Op->Asl.ExternalName);
1475     }
1476     else if (!(ThisNodeBtype & RequiredBtypes))
1477     {
1478         /*
1479          * Method returns a value, but the type is wrong
1480          */
1481         AnFormatBtype (StringBuffer, ThisNodeBtype);
1482         AnFormatBtype (StringBuffer2, RequiredBtypes);
1483
1484
1485         /*
1486          * The case where the method does not return any value at all
1487          * was already handled in the namespace cross reference
1488          * -- Only issue an error if the method in fact returns a value,
1489          * but it is of the wrong type
1490          */
1491         if (ThisNodeBtype != 0)
1492         {
1493             sprintf (MsgBuffer, "Method returns [%s], %s operator requires [%s]",
1494                         StringBuffer, OpInfo->Name, StringBuffer2);
1495
1496             AslError (ASL_ERROR, ASL_MSG_INVALID_TYPE, ArgOp, MsgBuffer);
1497         }
1498     }
1499 }
1500
1501
1502 /*******************************************************************************
1503  *
1504  * FUNCTION:    AnOperandTypecheckWalkBegin
1505  *
1506  * PARAMETERS:  ASL_WALK_CALLBACK
1507  *
1508  * RETURN:      Status
1509  *
1510  * DESCRIPTION: Descending callback for the analysis walk.  Check methods for :
1511  *              1) Initialized local variables
1512  *              2) Valid arguments
1513  *              3) Return types
1514  *
1515  ******************************************************************************/
1516
1517 ACPI_STATUS
1518 AnOperandTypecheckWalkBegin (
1519     ACPI_PARSE_OBJECT       *Op,
1520     UINT32                  Level,
1521     void                    *Context)
1522 {
1523
1524     return AE_OK;
1525 }
1526
1527
1528 /*******************************************************************************
1529  *
1530  * FUNCTION:    AnOperandTypecheckWalkEnd
1531  *
1532  * PARAMETERS:  ASL_WALK_CALLBACK
1533  *
1534  * RETURN:      Status
1535  *
1536  * DESCRIPTION: Ascending callback for analysis walk.  Complete method
1537  *              return analysis.
1538  *
1539  ******************************************************************************/
1540
1541 ACPI_STATUS
1542 AnOperandTypecheckWalkEnd (
1543     ACPI_PARSE_OBJECT       *Op,
1544     UINT32                  Level,
1545     void                    *Context)
1546 {
1547     const ACPI_OPCODE_INFO  *OpInfo;
1548     UINT32                  RuntimeArgTypes;
1549     UINT32                  RuntimeArgTypes2;
1550     UINT32                  RequiredBtypes;
1551     UINT32                  ThisNodeBtype;
1552     UINT32                  CommonBtypes;
1553     UINT32                  OpcodeClass;
1554     ACPI_PARSE_OBJECT       *ArgOp;
1555     UINT32                  ArgType;
1556
1557
1558     switch (Op->Asl.AmlOpcode)
1559     {
1560     case AML_RAW_DATA_BYTE:
1561     case AML_RAW_DATA_WORD:
1562     case AML_RAW_DATA_DWORD:
1563     case AML_RAW_DATA_QWORD:
1564     case AML_RAW_DATA_BUFFER:
1565     case AML_RAW_DATA_CHAIN:
1566     case AML_PACKAGE_LENGTH:
1567     case AML_UNASSIGNED_OPCODE:
1568     case AML_DEFAULT_ARG_OP:
1569
1570         /* Ignore the internal (compiler-only) AML opcodes */
1571
1572         return (AE_OK);
1573
1574     default:
1575         break;
1576     }
1577
1578     OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode);
1579     if (!OpInfo)
1580     {
1581         return (AE_OK);
1582     }
1583
1584     ArgOp           = Op->Asl.Child;
1585     RuntimeArgTypes = OpInfo->RuntimeArgs;
1586     OpcodeClass     = OpInfo->Class;
1587
1588
1589     /*
1590      * Special case for control opcodes IF/RETURN/WHILE since they
1591      * have no runtime arg list (at this time)
1592      */
1593     switch (Op->Asl.AmlOpcode)
1594     {
1595     case AML_IF_OP:
1596     case AML_WHILE_OP:
1597     case AML_RETURN_OP:
1598
1599         if (ArgOp->Asl.ParseOpcode == PARSEOP_METHODCALL)
1600         {
1601             /* The lone arg is a method call, check it */
1602
1603             RequiredBtypes = AnMapArgTypeToBtype (ARGI_INTEGER);
1604             if (Op->Asl.AmlOpcode == AML_RETURN_OP)
1605             {
1606                 RequiredBtypes = 0xFFFFFFFF;
1607             }
1608
1609             ThisNodeBtype = AnGetBtype (ArgOp);
1610             if (ThisNodeBtype == ACPI_UINT32_MAX)
1611             {
1612                 return (AE_OK);
1613             }
1614             AnCheckMethodReturnValue (Op, OpInfo, ArgOp, RequiredBtypes, ThisNodeBtype);
1615         }
1616         return (AE_OK);
1617
1618     default:
1619         break;
1620     }
1621
1622     /* Ignore the non-executable opcodes */
1623
1624     if (RuntimeArgTypes == ARGI_INVALID_OPCODE)
1625     {
1626         return (AE_OK);
1627     }
1628
1629     switch (OpcodeClass)
1630     {
1631     case AML_CLASS_EXECUTE:
1632     case AML_CLASS_CREATE:
1633     case AML_CLASS_CONTROL:
1634     case AML_CLASS_RETURN_VALUE:
1635
1636         /* TBD: Change class or fix typechecking for these */
1637
1638         if ((Op->Asl.AmlOpcode == AML_BUFFER_OP)        ||
1639             (Op->Asl.AmlOpcode == AML_PACKAGE_OP)       ||
1640             (Op->Asl.AmlOpcode == AML_VAR_PACKAGE_OP))
1641         {
1642             break;
1643         }
1644
1645         /* Reverse the runtime argument list */
1646
1647         RuntimeArgTypes2 = 0;
1648         while ((ArgType = GET_CURRENT_ARG_TYPE (RuntimeArgTypes)))
1649         {
1650             RuntimeArgTypes2 <<= ARG_TYPE_WIDTH;
1651             RuntimeArgTypes2 |= ArgType;
1652             INCREMENT_ARG_LIST (RuntimeArgTypes);
1653         }
1654
1655         while ((ArgType = GET_CURRENT_ARG_TYPE (RuntimeArgTypes2)))
1656         {
1657             RequiredBtypes = AnMapArgTypeToBtype (ArgType);
1658
1659             ThisNodeBtype = AnGetBtype (ArgOp);
1660             if (ThisNodeBtype == ACPI_UINT32_MAX)
1661             {
1662                 goto NextArgument;
1663             }
1664
1665             /* Examine the arg based on the required type of the arg */
1666
1667             switch (ArgType)
1668             {
1669             case ARGI_TARGETREF:
1670
1671                 if (ArgOp->Asl.ParseOpcode == PARSEOP_ZERO)
1672                 {
1673                     /* ZERO is the placeholder for "don't store result" */
1674
1675                     ThisNodeBtype = RequiredBtypes;
1676                     break;
1677                 }
1678
1679                 if (ArgOp->Asl.ParseOpcode == PARSEOP_INTEGER)
1680                 {
1681                     /*
1682                      * This is the case where an original reference to a resource
1683                      * descriptor field has been replaced by an (Integer) offset.
1684                      * These named fields are supported at compile-time only;
1685                      * the names are not passed to the interpreter (via the AML).
1686                      */
1687                     if ((ArgOp->Asl.Node->Type == ACPI_TYPE_LOCAL_RESOURCE_FIELD) ||
1688                         (ArgOp->Asl.Node->Type == ACPI_TYPE_LOCAL_RESOURCE))
1689                     {
1690                         AslError (ASL_ERROR, ASL_MSG_RESOURCE_FIELD, ArgOp, NULL);
1691                     }
1692                     else
1693                     {
1694                         AslError (ASL_ERROR, ASL_MSG_INVALID_TYPE, ArgOp, NULL);
1695                     }
1696                     break;
1697                 }
1698
1699                 if ((ArgOp->Asl.ParseOpcode == PARSEOP_METHODCALL) ||
1700                     (ArgOp->Asl.ParseOpcode == PARSEOP_DEREFOF))
1701                 {
1702                     break;
1703                 }
1704
1705                 ThisNodeBtype = RequiredBtypes;
1706                 break;
1707
1708
1709             case ARGI_REFERENCE:            /* References */
1710             case ARGI_INTEGER_REF:
1711             case ARGI_OBJECT_REF:
1712             case ARGI_DEVICE_REF:
1713
1714                 switch (ArgOp->Asl.ParseOpcode)
1715                 {
1716                 case PARSEOP_LOCAL0:
1717                 case PARSEOP_LOCAL1:
1718                 case PARSEOP_LOCAL2:
1719                 case PARSEOP_LOCAL3:
1720                 case PARSEOP_LOCAL4:
1721                 case PARSEOP_LOCAL5:
1722                 case PARSEOP_LOCAL6:
1723                 case PARSEOP_LOCAL7:
1724
1725                     /* TBD: implement analysis of current value (type) of the local */
1726                     /* For now, just treat any local as a typematch */
1727
1728                     /*ThisNodeBtype = RequiredBtypes;*/
1729                     break;
1730
1731                 case PARSEOP_ARG0:
1732                 case PARSEOP_ARG1:
1733                 case PARSEOP_ARG2:
1734                 case PARSEOP_ARG3:
1735                 case PARSEOP_ARG4:
1736                 case PARSEOP_ARG5:
1737                 case PARSEOP_ARG6:
1738
1739                     /* Hard to analyze argument types, sow we won't */
1740                     /* For now, just treat any arg as a typematch */
1741
1742                     /* ThisNodeBtype = RequiredBtypes; */
1743                     break;
1744
1745                 case PARSEOP_DEBUG:
1746                     break;
1747
1748                 case PARSEOP_REFOF:
1749                 case PARSEOP_INDEX:
1750                 default:
1751                     break;
1752
1753                 }
1754                 break;
1755
1756             case ARGI_INTEGER:
1757             default:
1758                 break;
1759             }
1760
1761
1762             CommonBtypes = ThisNodeBtype & RequiredBtypes;
1763
1764             if (ArgOp->Asl.ParseOpcode == PARSEOP_METHODCALL)
1765             {
1766                 /* Check a method call for a valid return value */
1767
1768                 AnCheckMethodReturnValue (Op, OpInfo, ArgOp, RequiredBtypes, ThisNodeBtype);
1769             }
1770
1771             /*
1772              * Now check if the actual type(s) match at least one
1773              * bit to the required type
1774              */
1775             else if (!CommonBtypes)
1776             {
1777                 /* No match -- this is a type mismatch error */
1778
1779                 AnFormatBtype (StringBuffer, ThisNodeBtype);
1780                 AnFormatBtype (StringBuffer2, RequiredBtypes);
1781
1782                 sprintf (MsgBuffer, "[%s] found, %s operator requires [%s]",
1783                             StringBuffer, OpInfo->Name, StringBuffer2);
1784
1785                 AslError (ASL_ERROR, ASL_MSG_INVALID_TYPE, ArgOp, MsgBuffer);
1786             }
1787
1788         NextArgument:
1789             ArgOp = ArgOp->Asl.Next;
1790             INCREMENT_ARG_LIST (RuntimeArgTypes2);
1791         }
1792         break;
1793
1794     default:
1795         break;
1796     }
1797
1798     return (AE_OK);
1799 }
1800
1801
1802 /*******************************************************************************
1803  *
1804  * FUNCTION:    AnOtherSemanticAnalysisWalkBegin
1805  *
1806  * PARAMETERS:  ASL_WALK_CALLBACK
1807  *
1808  * RETURN:      Status
1809  *
1810  * DESCRIPTION: Descending callback for the analysis walk.  Check methods for :
1811  *              1) Initialized local variables
1812  *              2) Valid arguments
1813  *              3) Return types
1814  *
1815  ******************************************************************************/
1816
1817 ACPI_STATUS
1818 AnOtherSemanticAnalysisWalkBegin (
1819     ACPI_PARSE_OBJECT       *Op,
1820     UINT32                  Level,
1821     void                    *Context)
1822 {
1823
1824     return AE_OK;
1825 }
1826
1827
1828 /*******************************************************************************
1829  *
1830  * FUNCTION:    AnOtherSemanticAnalysisWalkEnd
1831  *
1832  * PARAMETERS:  ASL_WALK_CALLBACK
1833  *
1834  * RETURN:      Status
1835  *
1836  * DESCRIPTION: Ascending callback for analysis walk.  Complete method
1837  *              return analysis.
1838  *
1839  ******************************************************************************/
1840
1841 ACPI_STATUS
1842 AnOtherSemanticAnalysisWalkEnd (
1843     ACPI_PARSE_OBJECT       *Op,
1844     UINT32                  Level,
1845     void                    *Context)
1846 {
1847
1848     return AE_OK;
1849
1850 }