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