xref: /freebsd/sys/contrib/dev/acpica/compiler/aslanalyze.c (revision 6b3455a7665208c366849f0b2b3bc916fb97516e)
1 
2 /******************************************************************************
3  *
4  * Module Name: aslanalyze.c - check for semantic errors
5  *              $Revision: 80 $
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                 "Null attached Nsnode: [%s] at line %d\n",
458                 Op->Asl.ParseOpName, Op->Asl.LineNumber);
459             return ACPI_UINT32_MAX;
460         }
461 
462         ThisNodeBtype = AnMapEtypeToBtype (Node->Type);
463 
464         /*
465          * Since it was a named reference, enable the
466          * reference bit also
467          */
468         ThisNodeBtype |= ACPI_BTYPE_REFERENCE;
469 
470         if (Op->Asl.ParseOpcode == PARSEOP_METHODCALL)
471         {
472             ReferencedNode = ACPI_CAST_PTR (ACPI_PARSE_OBJECT, Node->Object);
473             if (!ReferencedNode)
474             {
475                printf ("No back ptr to Op: type %X\n", Node->Type);
476                return ACPI_UINT32_MAX;
477             }
478 
479             if (ReferencedNode->Asl.CompileFlags & NODE_METHOD_TYPED)
480             {
481                 ThisNodeBtype = ReferencedNode->Asl.AcpiBtype;
482             }
483             else
484             {
485                 return (ACPI_UINT32_MAX -1);
486             }
487         }
488     }
489     else
490     {
491         ThisNodeBtype = Op->Asl.AcpiBtype;
492     }
493 
494     return (ThisNodeBtype);
495 }
496 
497 
498 /*******************************************************************************
499  *
500  * FUNCTION:    AnCheckForReservedName
501  *
502  * PARAMETERS:  Op              - A parse node
503  *              Name            - NameSeg to check
504  *
505  * RETURN:      None
506  *
507  * DESCRIPTION: Check a NameSeg against the reserved list.
508  *
509  ******************************************************************************/
510 
511 #define ACPI_VALID_RESERVED_NAME_MAX    0x80000000
512 #define ACPI_NOT_RESERVED_NAME          ACPI_UINT32_MAX
513 #define ACPI_PREDEFINED_NAME            (ACPI_UINT32_MAX - 1)
514 #define ACPI_EVENT_RESERVED_NAME        (ACPI_UINT32_MAX - 2)
515 #define ACPI_COMPILER_RESERVED_NAME     (ACPI_UINT32_MAX - 3)
516 
517 UINT32
518 AnCheckForReservedName (
519     ACPI_PARSE_OBJECT       *Op,
520     char                    *Name)
521 {
522     UINT32                  i;
523 
524 
525     if (Name[0] == 0)
526     {
527         AcpiOsPrintf ("Found a null name, external = %s\n", Op->Asl.ExternalName);
528     }
529 
530     /* All reserved names are prefixed with a single underscore */
531 
532     if (Name[0] != '_')
533     {
534         return (ACPI_NOT_RESERVED_NAME);
535     }
536 
537     /* Check for a standard reserved method name */
538 
539     for (i = 0; ReservedMethods[i].Name; i++)
540     {
541         if (!ACPI_STRNCMP (Name, ReservedMethods[i].Name, ACPI_NAME_SIZE))
542         {
543             if (ReservedMethods[i].Flags & ASL_RSVD_SCOPE)
544             {
545                 AslError (ASL_ERROR, ASL_MSG_RESERVED_WORD, Op, Op->Asl.ExternalName);
546                 return (ACPI_PREDEFINED_NAME);
547             }
548             else if (ReservedMethods[i].Flags & ASL_RSVD_RESOURCE_NAME)
549             {
550                 AslError (ASL_ERROR, ASL_MSG_RESERVED_WORD, Op, Op->Asl.ExternalName);
551                 return (ACPI_PREDEFINED_NAME);
552             }
553 
554             /* Return index into reserved array */
555 
556             return i;
557         }
558     }
559 
560     /*
561      * Now check for the "special" reserved names --
562      * GPE:  _Lxx
563      * GPE:  _Exx
564      * EC:   _Qxx
565      */
566     if ((Name[1] == 'L') ||
567         (Name[1] == 'E') ||
568         (Name[1] == 'Q'))
569     {
570         /* The next two characters must be hex digits */
571 
572         if ((isxdigit (Name[2])) &&
573             (isxdigit (Name[3])))
574         {
575             return (ACPI_EVENT_RESERVED_NAME);
576         }
577     }
578 
579 
580     /* Check for the names reserved for the compiler itself: _T_x */
581 
582     else if ((Op->Asl.ExternalName[1] == 'T') &&
583              (Op->Asl.ExternalName[2] == '_'))
584     {
585         AslError (ASL_ERROR, ASL_MSG_RESERVED_WORD, Op, Op->Asl.ExternalName);
586         return (ACPI_COMPILER_RESERVED_NAME);
587     }
588 
589     /*
590      * The name didn't match any of the known reserved names.  Flag it as a
591      * warning, since the entire namespace starting with an underscore is
592      * reserved by the ACPI spec.
593      */
594     AslError (ASL_WARNING, ASL_MSG_UNKNOWN_RESERVED_NAME, Op, Op->Asl.ExternalName);
595 
596     return (ACPI_NOT_RESERVED_NAME);
597 }
598 
599 
600 /*******************************************************************************
601  *
602  * FUNCTION:    AnCheckForReservedMethod
603  *
604  * PARAMETERS:  Op              - A parse node of type "METHOD".
605  *              MethodInfo      - Saved info about this method
606  *
607  * RETURN:      None
608  *
609  * DESCRIPTION: If method is a reserved name, check that the number of arguments
610  *              and the return type (returns a value or not) is correct.
611  *
612  ******************************************************************************/
613 
614 void
615 AnCheckForReservedMethod (
616     ACPI_PARSE_OBJECT       *Op,
617     ASL_METHOD_INFO         *MethodInfo)
618 {
619     UINT32                  Index;
620 
621 
622     /* Check for a match against the reserved name list */
623 
624     Index = AnCheckForReservedName (Op, Op->Asl.NameSeg);
625 
626     switch (Index)
627     {
628     case ACPI_NOT_RESERVED_NAME:
629     case ACPI_PREDEFINED_NAME:
630     case ACPI_COMPILER_RESERVED_NAME:
631 
632         /* Just return, nothing to do */
633         break;
634 
635 
636     case ACPI_EVENT_RESERVED_NAME:
637 
638         Gbl_ReservedMethods++;
639 
640         /* NumArguments must be zero for all _Lxx, _Exx, and _Qxx methods */
641 
642         if (MethodInfo->NumArguments != 0)
643         {
644             sprintf (MsgBuffer, " %s requires %d",
645                         Op->Asl.ExternalName, 0);
646 
647             AslError (ASL_WARNING, ASL_MSG_RESERVED_ARG_COUNT_HI, Op, MsgBuffer);
648         }
649         break;
650 
651 
652     default:
653 
654         Gbl_ReservedMethods++;
655 
656         /* Matched a reserved method name */
657 
658         if (MethodInfo->NumArguments != ReservedMethods[Index].NumArguments)
659         {
660             sprintf (MsgBuffer, " %s requires %d",
661                         ReservedMethods[Index].Name,
662                         ReservedMethods[Index].NumArguments);
663 
664             if (MethodInfo->NumArguments > ReservedMethods[Index].NumArguments)
665             {
666                 AslError (ASL_WARNING, ASL_MSG_RESERVED_ARG_COUNT_HI, Op, MsgBuffer);
667             }
668             else
669             {
670                 AslError (ASL_WARNING, ASL_MSG_RESERVED_ARG_COUNT_LO, Op, MsgBuffer);
671             }
672         }
673 
674         if (MethodInfo->NumReturnNoValue &&
675             ReservedMethods[Index].Flags & ASL_RSVD_RETURN_VALUE)
676         {
677             sprintf (MsgBuffer, "%s", ReservedMethods[Index].Name);
678 
679             AslError (ASL_WARNING, ASL_MSG_RESERVED_RETURN_VALUE, Op, MsgBuffer);
680         }
681         break;
682     }
683 }
684 
685 
686 /*******************************************************************************
687  *
688  * FUNCTION:    AnMethodAnalysisWalkBegin
689  *
690  * PARAMETERS:  ASL_WALK_CALLBACK
691  *
692  * RETURN:      Status
693  *
694  * DESCRIPTION: Descending callback for the analysis walk.  Check methods for :
695  *              1) Initialized local variables
696  *              2) Valid arguments
697  *              3) Return types
698  *
699  ******************************************************************************/
700 
701 ACPI_STATUS
702 AnMethodAnalysisWalkBegin (
703     ACPI_PARSE_OBJECT       *Op,
704     UINT32                  Level,
705     void                    *Context)
706 {
707     ASL_ANALYSIS_WALK_INFO  *WalkInfo = (ASL_ANALYSIS_WALK_INFO *) Context;
708     ASL_METHOD_INFO         *MethodInfo = WalkInfo->MethodStack;
709     ACPI_PARSE_OBJECT       *Next;
710     UINT32                  RegisterNumber;
711     UINT32                  i;
712     char                    LocalName[] = "Local0";
713     char                    ArgName[] = "Arg0";
714 
715 
716     ACPI_FUNCTION_NAME ("AnMethodAnalysisWalkBegin");
717 
718 
719     switch (Op->Asl.ParseOpcode)
720     {
721     case PARSEOP_METHOD:
722 
723         TotalMethods++;
724 
725         /*
726          * Create and init method info
727          */
728         MethodInfo       = UtLocalCalloc (sizeof (ASL_METHOD_INFO));
729         MethodInfo->Next = WalkInfo->MethodStack;
730         MethodInfo->Op = Op;
731 
732         WalkInfo->MethodStack = MethodInfo;
733 
734         /* Get the NumArguments node */
735 
736         Next = Op->Asl.Child;
737         Next = Next->Asl.Next;
738         MethodInfo->NumArguments = (UINT8) (((UINT8) Next->Asl.Value.Integer) & 0x07);
739 
740         /*
741          * Actual arguments are initialized at method entry.
742          * All other ArgX "registers" can be used as locals, so we
743          * track their initialization.
744          */
745         for (i = 0; i < MethodInfo->NumArguments; i++)
746         {
747             MethodInfo->ArgInitialized[i] = TRUE;
748         }
749 
750         break;
751 
752 
753     case PARSEOP_METHODCALL:
754 
755         if (MethodInfo &&
756            (Op->Asl.Node == MethodInfo->Op->Asl.Node))
757         {
758             AslError (ASL_REMARK, ASL_MSG_RECURSION, Op, Op->Asl.ExternalName);
759         }
760         break;
761 
762 
763     case PARSEOP_LOCAL0:
764     case PARSEOP_LOCAL1:
765     case PARSEOP_LOCAL2:
766     case PARSEOP_LOCAL3:
767     case PARSEOP_LOCAL4:
768     case PARSEOP_LOCAL5:
769     case PARSEOP_LOCAL6:
770     case PARSEOP_LOCAL7:
771 
772         if (!MethodInfo)
773         {
774             /* Probably was an error in the method declaration, no additional error here */
775 
776             ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "%p, No parent method\n", Op));
777             return (AE_ERROR);
778         }
779 
780         RegisterNumber = (Op->Asl.AmlOpcode & 0x000F);
781 
782         /*
783          * If the local is being used as a target, mark the local
784          * initialized
785          */
786         if (Op->Asl.CompileFlags & NODE_IS_TARGET)
787         {
788             MethodInfo->LocalInitialized[RegisterNumber] = TRUE;
789         }
790 
791         /*
792          * Otherwise, this is a reference, check if the local
793          * has been previously initialized.
794          */
795         else if (!MethodInfo->LocalInitialized[RegisterNumber])
796         {
797             LocalName[strlen (LocalName) -1] = (char) (RegisterNumber + 0x30);
798             AslError (ASL_ERROR, ASL_MSG_LOCAL_INIT, Op, LocalName);
799         }
800         break;
801 
802 
803     case PARSEOP_ARG0:
804     case PARSEOP_ARG1:
805     case PARSEOP_ARG2:
806     case PARSEOP_ARG3:
807     case PARSEOP_ARG4:
808     case PARSEOP_ARG5:
809     case PARSEOP_ARG6:
810 
811         if (!MethodInfo)
812         {
813             /* Probably was an error in the method declaration, no additional error here */
814 
815             ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "%p, No parent method\n", Op));
816             return (AE_ERROR);
817         }
818 
819         RegisterNumber = (Op->Asl.AmlOpcode & 0x000F) - 8;
820         ArgName[strlen (ArgName) -1] = (char) (RegisterNumber + 0x30);
821 
822         /*
823          * If the Arg is being used as a target, mark the local
824          * initialized
825          */
826         if (Op->Asl.CompileFlags & NODE_IS_TARGET)
827         {
828             MethodInfo->ArgInitialized[RegisterNumber] = TRUE;
829         }
830 
831         /*
832          * Otherwise, this is a reference, check if the Arg
833          * has been previously initialized.
834          */
835         else if (!MethodInfo->ArgInitialized[RegisterNumber])
836         {
837             AslError (ASL_ERROR, ASL_MSG_ARG_INIT, Op, ArgName);
838         }
839 
840         /* Flag this arg if it is not a "real" argument to the method */
841 
842         if (RegisterNumber >= MethodInfo->NumArguments)
843         {
844             AslError (ASL_REMARK, ASL_MSG_NOT_PARAMETER, Op, ArgName);
845         }
846         break;
847 
848 
849     case PARSEOP_RETURN:
850 
851         if (!MethodInfo)
852         {
853             /* Probably was an error in the method declaration, no additional error here */
854 
855             ACPI_DEBUG_PRINT ((ACPI_DB_WARN, "%p, No parent method\n", Op));
856             return (AE_ERROR);
857         }
858 
859         /* Child indicates a return value */
860 
861         if ((Op->Asl.Child) &&
862             (Op->Asl.Child->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG))
863         {
864             MethodInfo->NumReturnWithValue++;
865         }
866         else
867         {
868             MethodInfo->NumReturnNoValue++;
869         }
870         break;
871 
872 
873     case PARSEOP_BREAK:
874     case PARSEOP_CONTINUE:
875 
876         Next = Op->Asl.Parent;
877         while (Next)
878         {
879             if (Next->Asl.ParseOpcode == PARSEOP_WHILE)
880             {
881                 break;
882             }
883             Next = Next->Asl.Parent;
884         }
885 
886         if (!Next)
887         {
888             AslError (ASL_ERROR, ASL_MSG_NO_WHILE, Op, NULL);
889         }
890         break;
891 
892 
893     case PARSEOP_STALL:
894 
895         if (Op->Asl.Child->Asl.Value.Integer > ACPI_UINT8_MAX)
896         {
897             AslError (ASL_ERROR, ASL_MSG_INVALID_TIME, Op, NULL);
898         }
899         break;
900 
901 
902     case PARSEOP_DEVICE:
903     case PARSEOP_EVENT:
904     case PARSEOP_MUTEX:
905     case PARSEOP_OPERATIONREGION:
906     case PARSEOP_POWERRESOURCE:
907     case PARSEOP_PROCESSOR:
908     case PARSEOP_THERMALZONE:
909 
910         /*
911          * The first operand is a name to be created in the namespace.
912          * Check against the reserved list.
913          */
914         i = AnCheckForReservedName (Op, Op->Asl.NameSeg);
915         if (i < ACPI_VALID_RESERVED_NAME_MAX)
916         {
917             AslError (ASL_ERROR, ASL_MSG_RESERVED_USE, Op, Op->Asl.ExternalName);
918         }
919         break;
920 
921 
922     case PARSEOP_NAME:
923 
924         i = AnCheckForReservedName (Op, Op->Asl.NameSeg);
925         if (i < ACPI_VALID_RESERVED_NAME_MAX)
926         {
927             if (ReservedMethods[i].NumArguments > 0)
928             {
929                 /*
930                  * This reserved name must be a control method because
931                  * it must have arguments
932                  */
933                 AslError (ASL_ERROR, ASL_MSG_RESERVED_METHOD, Op, "with arguments");
934             }
935 
936             /*
937              * Typechecking for _HID
938              */
939             else if (!ACPI_STRCMP (METHOD_NAME__HID, ReservedMethods[i].Name))
940             {
941                 /* Examine the second operand to typecheck it */
942 
943                 Next = Op->Asl.Child->Asl.Next;
944 
945                 if ((Next->Asl.ParseOpcode != PARSEOP_INTEGER) &&
946                     (Next->Asl.ParseOpcode != PARSEOP_STRING_LITERAL))
947                 {
948                     /* _HID must be a string or an integer */
949 
950                     AslError (ASL_ERROR, ASL_MSG_RESERVED_OPERAND_TYPE, Next, "String or Integer");
951                 }
952 
953                 if (Next->Asl.ParseOpcode == PARSEOP_STRING_LITERAL)
954                 {
955                     /*
956                      * _HID is a string, all characters must be alphanumeric.
957                      * One of the things we want to catch here is the use of
958                      * a leading asterisk in the string.
959                      */
960                     for (i = 0; Next->Asl.Value.String[i]; i++)
961                     {
962                         if (!isalnum (Next->Asl.Value.String[i]))
963                         {
964                             AslError (ASL_ERROR, ASL_MSG_ALPHANUMERIC_STRING, Next, Next->Asl.Value.String);
965                             break;
966                         }
967                     }
968                 }
969             }
970         }
971 
972         break;
973 
974 
975     default:
976         break;
977     }
978 
979     return AE_OK;
980 }
981 
982 
983 /*******************************************************************************
984  *
985  * FUNCTION:    AnLastStatementIsReturn
986  *
987  * PARAMETERS:  Op            - A method parse node
988  *
989  * RETURN:      TRUE if last statement is an ASL RETURN.  False otherwise
990  *
991  * DESCRIPTION: Walk down the list of top level statements within a method
992  *              to find the last one.  Check if that last statement is in
993  *              fact a RETURN statement.
994  *
995  ******************************************************************************/
996 
997 BOOLEAN
998 AnLastStatementIsReturn (
999     ACPI_PARSE_OBJECT       *Op)
1000 {
1001     ACPI_PARSE_OBJECT       *Next;
1002 
1003 
1004     /*
1005      * Check if last statement is a return
1006      */
1007     Next = ASL_GET_CHILD_NODE (Op);
1008     while (Next)
1009     {
1010         if ((!Next->Asl.Next) &&
1011             (Next->Asl.ParseOpcode == PARSEOP_RETURN))
1012         {
1013             return TRUE;
1014         }
1015 
1016         Next = ASL_GET_PEER_NODE (Next);
1017     }
1018 
1019     return FALSE;
1020 }
1021 
1022 
1023 /*******************************************************************************
1024  *
1025  * FUNCTION:    AnMethodAnalysisWalkEnd
1026  *
1027  * PARAMETERS:  ASL_WALK_CALLBACK
1028  *
1029  * RETURN:      Status
1030  *
1031  * DESCRIPTION: Ascending callback for analysis walk.  Complete method
1032  *              return analysis.
1033  *
1034  ******************************************************************************/
1035 
1036 ACPI_STATUS
1037 AnMethodAnalysisWalkEnd (
1038     ACPI_PARSE_OBJECT       *Op,
1039     UINT32                  Level,
1040     void                    *Context)
1041 {
1042     ASL_ANALYSIS_WALK_INFO  *WalkInfo = (ASL_ANALYSIS_WALK_INFO *) Context;
1043     ASL_METHOD_INFO         *MethodInfo = WalkInfo->MethodStack;
1044 
1045 
1046     switch (Op->Asl.ParseOpcode)
1047     {
1048     case PARSEOP_METHOD:
1049     case PARSEOP_RETURN:
1050         if (!MethodInfo)
1051         {
1052             printf ("No method info for method! [%s]\n", Op->Asl.Namepath);
1053             AslError (ASL_ERROR, ASL_MSG_COMPILER_INTERNAL, Op, "No method info for this method");
1054             CmCleanupAndExit ();
1055             return (AE_AML_INTERNAL);
1056         }
1057         break;
1058 
1059     default:
1060         break;
1061     }
1062 
1063     switch (Op->Asl.ParseOpcode)
1064     {
1065     case PARSEOP_METHOD:
1066 
1067         WalkInfo->MethodStack = MethodInfo->Next;
1068 
1069         /*
1070          * Check if there is no return statement at the end of the
1071          * method AND we can actually get there -- i.e., the execution
1072          * of the method can possibly terminate without a return statement.
1073          */
1074         if ((!AnLastStatementIsReturn (Op)) &&
1075             (!(Op->Asl.CompileFlags & NODE_HAS_NO_EXIT)))
1076         {
1077             /*
1078              * No return statement, and execution can possibly exit
1079              * via this path.  This is equivalent to Return ()
1080              */
1081             MethodInfo->NumReturnNoValue++;
1082         }
1083 
1084         /*
1085          * Check for case where some return statements have a return value
1086          * and some do not.  Exit without a return statement is a return with
1087          * no value
1088          */
1089         if (MethodInfo->NumReturnNoValue &&
1090             MethodInfo->NumReturnWithValue)
1091         {
1092             AslError (ASL_WARNING, ASL_MSG_RETURN_TYPES, Op, Op->Asl.ExternalName);
1093         }
1094 
1095         /*
1096          * If there are any RETURN() statements with no value, or there is a
1097          * control path that allows the method to exit without a return value,
1098          * we mark the method as a method that does not return a value.  This
1099          * knowledge can be used to check method invocations that expect a
1100          * returned value.
1101          */
1102         if (MethodInfo->NumReturnNoValue)
1103         {
1104             if (MethodInfo->NumReturnWithValue)
1105             {
1106                 Op->Asl.CompileFlags |= NODE_METHOD_SOME_NO_RETVAL;
1107             }
1108             else
1109             {
1110                 Op->Asl.CompileFlags |= NODE_METHOD_NO_RETVAL;
1111             }
1112         }
1113 
1114         /*
1115          * Check predefined method names for correct return behavior
1116          * and correct number of arguments
1117          */
1118         AnCheckForReservedMethod (Op, MethodInfo);
1119         ACPI_MEM_FREE (MethodInfo);
1120         break;
1121 
1122 
1123     case PARSEOP_RETURN:
1124 
1125         /*
1126          * The parent block does not "exit" and continue execution -- the
1127          * method is terminated here with the Return() statement.
1128          */
1129         Op->Asl.Parent->Asl.CompileFlags |= NODE_HAS_NO_EXIT;
1130         Op->Asl.ParentMethod = MethodInfo->Op;      /* Used in the "typing" pass later */
1131 
1132         /*
1133          * If there is a peer node after the return statement, then this
1134          * node is unreachable code -- i.e., it won't be executed because of the
1135          * preceeding Return() statement.
1136          */
1137         if (Op->Asl.Next)
1138         {
1139             AslError (ASL_WARNING, ASL_MSG_UNREACHABLE_CODE, Op->Asl.Next, NULL);
1140         }
1141         break;
1142 
1143 
1144     case PARSEOP_IF:
1145 
1146         if ((Op->Asl.CompileFlags & NODE_HAS_NO_EXIT) &&
1147             (Op->Asl.Next) &&
1148             (Op->Asl.Next->Asl.ParseOpcode == PARSEOP_ELSE))
1149         {
1150             /*
1151              * This IF has a corresponding ELSE.  The IF block has no exit,
1152              * (it contains an unconditional Return)
1153              * mark the ELSE block to remember this fact.
1154              */
1155             Op->Asl.Next->Asl.CompileFlags |= NODE_IF_HAS_NO_EXIT;
1156         }
1157         break;
1158 
1159 
1160     case PARSEOP_ELSE:
1161 
1162         if ((Op->Asl.CompileFlags & NODE_HAS_NO_EXIT) &&
1163             (Op->Asl.CompileFlags & NODE_IF_HAS_NO_EXIT))
1164         {
1165             /*
1166              * This ELSE block has no exit and the corresponding IF block
1167              * has no exit either.  Therefore, the parent node has no exit.
1168              */
1169             Op->Asl.Parent->Asl.CompileFlags |= NODE_HAS_NO_EXIT;
1170         }
1171         break;
1172 
1173 
1174     default:
1175 
1176         if ((Op->Asl.CompileFlags & NODE_HAS_NO_EXIT) &&
1177             (Op->Asl.Parent))
1178         {
1179             /* If this node has no exit, then the parent has no exit either */
1180 
1181             Op->Asl.Parent->Asl.CompileFlags |= NODE_HAS_NO_EXIT;
1182         }
1183         break;
1184     }
1185 
1186     return AE_OK;
1187 }
1188 
1189 
1190 /*******************************************************************************
1191  *
1192  * FUNCTION:    AnMethodTypingWalkBegin
1193  *
1194  * PARAMETERS:  ASL_WALK_CALLBACK
1195  *
1196  * RETURN:      Status
1197  *
1198  * DESCRIPTION: Descending callback for the typing walk.
1199  *
1200  ******************************************************************************/
1201 
1202 ACPI_STATUS
1203 AnMethodTypingWalkBegin (
1204     ACPI_PARSE_OBJECT       *Op,
1205     UINT32                  Level,
1206     void                    *Context)
1207 {
1208 
1209     return AE_OK;
1210 }
1211 
1212 
1213 /*******************************************************************************
1214  *
1215  * FUNCTION:    AnMethodTypingWalkEnd
1216  *
1217  * PARAMETERS:  ASL_WALK_CALLBACK
1218  *
1219  * RETURN:      Status
1220  *
1221  * DESCRIPTION: Ascending callback for typing walk.  Complete method
1222  *              return analysis.  Check methods for :
1223  *              1) Initialized local variables
1224  *              2) Valid arguments
1225  *              3) Return types
1226  *
1227  ******************************************************************************/
1228 
1229 ACPI_STATUS
1230 AnMethodTypingWalkEnd (
1231     ACPI_PARSE_OBJECT       *Op,
1232     UINT32                  Level,
1233     void                    *Context)
1234 {
1235     UINT32                  ThisNodeBtype;
1236 
1237 
1238     switch (Op->Asl.ParseOpcode)
1239     {
1240     case PARSEOP_METHOD:
1241 
1242         Op->Asl.CompileFlags |= NODE_METHOD_TYPED;
1243         break;
1244 
1245     case PARSEOP_RETURN:
1246 
1247         if ((Op->Asl.Child) &&
1248             (Op->Asl.Child->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG))
1249         {
1250             ThisNodeBtype = AnGetBtype (Op->Asl.Child);
1251 
1252             if ((Op->Asl.Child->Asl.ParseOpcode == PARSEOP_METHODCALL) &&
1253                 (ThisNodeBtype == (ACPI_UINT32_MAX -1)))
1254             {
1255                 /*
1256                  * The method is untyped at this time (typically a forward reference).
1257                  * We must recursively type the method here
1258                  */
1259                 TrWalkParseTree (ACPI_CAST_PTR (ACPI_PARSE_OBJECT, Op->Asl.Child->Asl.Node->Object),
1260                         ASL_WALK_VISIT_TWICE, AnMethodTypingWalkBegin,
1261                         AnMethodTypingWalkEnd, NULL);
1262 
1263                 ThisNodeBtype = AnGetBtype (Op->Asl.Child);
1264             }
1265 
1266             /* Returns a value, get it's type */
1267 
1268             if (Op->Asl.ParentMethod)
1269             {
1270                 Op->Asl.ParentMethod->Asl.AcpiBtype |= ThisNodeBtype;
1271             }
1272         }
1273         break;
1274 
1275     default:
1276         break;
1277     }
1278 
1279     return AE_OK;
1280 }
1281 
1282 
1283 /*******************************************************************************
1284  *
1285  * FUNCTION:    AnCheckMethodReturnValue
1286  *
1287  * PARAMETERS:  Op                  - Parent
1288  *              OpInfo              - Parent info
1289  *              ArgOp               - Method invocation op
1290  *              RequiredBtypes      - What caller requires
1291  *              ThisNodeBtype       - What this node returns (if anything)
1292  *
1293  * RETURN:      None
1294  *
1295  * DESCRIPTION: Check a method invocation for 1) A return value and if it does
1296  *              in fact return a value, 2) check the type of the return value.
1297  *
1298  ******************************************************************************/
1299 
1300 void
1301 AnCheckMethodReturnValue (
1302     ACPI_PARSE_OBJECT       *Op,
1303     const ACPI_OPCODE_INFO  *OpInfo,
1304     ACPI_PARSE_OBJECT       *ArgOp,
1305     UINT32                  RequiredBtypes,
1306     UINT32                  ThisNodeBtype)
1307 {
1308     ACPI_PARSE_OBJECT       *OwningOp;
1309     ACPI_NAMESPACE_NODE     *Node;
1310 
1311 
1312     Node = ArgOp->Asl.Node;
1313 
1314 
1315     /* Examine the parent op of this method */
1316 
1317     OwningOp = ACPI_CAST_PTR (ACPI_PARSE_OBJECT, Node->Object);
1318     if (OwningOp->Asl.CompileFlags & NODE_METHOD_NO_RETVAL)
1319     {
1320         /*
1321          * Method NEVER returns a value
1322          */
1323         AslError (ASL_ERROR, ASL_MSG_NO_RETVAL, Op, Op->Asl.ExternalName);
1324     }
1325     else if (OwningOp->Asl.CompileFlags & NODE_METHOD_SOME_NO_RETVAL)
1326     {
1327         /*
1328          * Method SOMETIMES returns a value, SOMETIMES not
1329          */
1330         AslError (ASL_WARNING, ASL_MSG_SOME_NO_RETVAL, Op, Op->Asl.ExternalName);
1331     }
1332     else if (!(ThisNodeBtype & RequiredBtypes))
1333     {
1334         /*
1335          * Method returns a value, but the type is wrong
1336          */
1337         AnFormatBtype (StringBuffer, ThisNodeBtype);
1338         AnFormatBtype (StringBuffer2, RequiredBtypes);
1339 
1340 
1341         /*
1342          * The case where the method does not return any value at all
1343          * was already handled in the namespace cross reference
1344          * -- Only issue an error if the method in fact returns a value,
1345          * but it is of the wrong type
1346          */
1347         if (ThisNodeBtype != 0)
1348         {
1349             sprintf (MsgBuffer, "Method returns [%s], %s operator requires [%s]",
1350                         StringBuffer, OpInfo->Name, StringBuffer2);
1351 
1352             AslError (ASL_ERROR, ASL_MSG_INVALID_TYPE, ArgOp, MsgBuffer);
1353         }
1354     }
1355 }
1356 
1357 
1358 /*******************************************************************************
1359  *
1360  * FUNCTION:    AnOperandTypecheckWalkBegin
1361  *
1362  * PARAMETERS:  ASL_WALK_CALLBACK
1363  *
1364  * RETURN:      Status
1365  *
1366  * DESCRIPTION: Descending callback for the analysis walk.  Check methods for :
1367  *              1) Initialized local variables
1368  *              2) Valid arguments
1369  *              3) Return types
1370  *
1371  ******************************************************************************/
1372 
1373 ACPI_STATUS
1374 AnOperandTypecheckWalkBegin (
1375     ACPI_PARSE_OBJECT       *Op,
1376     UINT32                  Level,
1377     void                    *Context)
1378 {
1379 
1380     return AE_OK;
1381 }
1382 
1383 
1384 /*******************************************************************************
1385  *
1386  * FUNCTION:    AnOperandTypecheckWalkEnd
1387  *
1388  * PARAMETERS:  ASL_WALK_CALLBACK
1389  *
1390  * RETURN:      Status
1391  *
1392  * DESCRIPTION: Ascending callback for analysis walk.  Complete method
1393  *              return analysis.
1394  *
1395  ******************************************************************************/
1396 
1397 ACPI_STATUS
1398 AnOperandTypecheckWalkEnd (
1399     ACPI_PARSE_OBJECT       *Op,
1400     UINT32                  Level,
1401     void                    *Context)
1402 {
1403     const ACPI_OPCODE_INFO  *OpInfo;
1404     UINT32                  RuntimeArgTypes;
1405     UINT32                  RuntimeArgTypes2;
1406     UINT32                  RequiredBtypes;
1407     UINT32                  ThisNodeBtype;
1408     UINT32                  CommonBtypes;
1409     UINT32                  OpcodeClass;
1410     ACPI_PARSE_OBJECT       *ArgOp;
1411     UINT32                  ArgType;
1412 
1413 
1414     switch (Op->Asl.AmlOpcode)
1415     {
1416     case AML_RAW_DATA_BYTE:
1417     case AML_RAW_DATA_WORD:
1418     case AML_RAW_DATA_DWORD:
1419     case AML_RAW_DATA_QWORD:
1420     case AML_RAW_DATA_BUFFER:
1421     case AML_RAW_DATA_CHAIN:
1422     case AML_PACKAGE_LENGTH:
1423     case AML_UNASSIGNED_OPCODE:
1424     case AML_DEFAULT_ARG_OP:
1425 
1426         /* Ignore the internal (compiler-only) AML opcodes */
1427 
1428         return (AE_OK);
1429 
1430     default:
1431         break;
1432     }
1433 
1434     OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode);
1435     if (!OpInfo)
1436     {
1437         return (AE_OK);
1438     }
1439 
1440     ArgOp           = Op->Asl.Child;
1441     RuntimeArgTypes = OpInfo->RuntimeArgs;
1442     OpcodeClass     = OpInfo->Class;
1443 
1444 
1445     /*
1446      * Special case for control opcodes IF/RETURN/WHILE since they
1447      * have no runtime arg list (at this time)
1448      */
1449     switch (Op->Asl.AmlOpcode)
1450     {
1451     case AML_IF_OP:
1452     case AML_WHILE_OP:
1453     case AML_RETURN_OP:
1454 
1455         if (ArgOp->Asl.ParseOpcode == PARSEOP_METHODCALL)
1456         {
1457             /* The lone arg is a method call, check it */
1458 
1459             RequiredBtypes = AnMapArgTypeToBtype (ARGI_INTEGER);
1460             if (Op->Asl.AmlOpcode == AML_RETURN_OP)
1461             {
1462                 RequiredBtypes = 0xFFFFFFFF;
1463             }
1464 
1465             ThisNodeBtype = AnGetBtype (ArgOp);
1466             if (ThisNodeBtype == ACPI_UINT32_MAX)
1467             {
1468                 return (AE_OK);
1469             }
1470             AnCheckMethodReturnValue (Op, OpInfo, ArgOp, RequiredBtypes, ThisNodeBtype);
1471         }
1472         return (AE_OK);
1473 
1474     default:
1475         break;
1476     }
1477 
1478     /* Ignore the non-executable opcodes */
1479 
1480     if (RuntimeArgTypes == ARGI_INVALID_OPCODE)
1481     {
1482         return (AE_OK);
1483     }
1484 
1485     switch (OpcodeClass)
1486     {
1487     case AML_CLASS_EXECUTE:
1488     case AML_CLASS_CREATE:
1489     case AML_CLASS_CONTROL:
1490     case AML_CLASS_RETURN_VALUE:
1491 
1492         /* TBD: Change class or fix typechecking for these */
1493 
1494         if ((Op->Asl.AmlOpcode == AML_BUFFER_OP)        ||
1495             (Op->Asl.AmlOpcode == AML_PACKAGE_OP)       ||
1496             (Op->Asl.AmlOpcode == AML_VAR_PACKAGE_OP))
1497         {
1498             break;
1499         }
1500 
1501         /* Reverse the runtime argument list */
1502 
1503         RuntimeArgTypes2 = 0;
1504         while ((ArgType = GET_CURRENT_ARG_TYPE (RuntimeArgTypes)))
1505         {
1506             RuntimeArgTypes2 <<= ARG_TYPE_WIDTH;
1507             RuntimeArgTypes2 |= ArgType;
1508             INCREMENT_ARG_LIST (RuntimeArgTypes);
1509         }
1510 
1511         while ((ArgType = GET_CURRENT_ARG_TYPE (RuntimeArgTypes2)))
1512         {
1513             RequiredBtypes = AnMapArgTypeToBtype (ArgType);
1514 
1515             ThisNodeBtype = AnGetBtype (ArgOp);
1516             if (ThisNodeBtype == ACPI_UINT32_MAX)
1517             {
1518                 goto NextArgument;
1519             }
1520 
1521             /* Examine the arg based on the required type of the arg */
1522 
1523             switch (ArgType)
1524             {
1525             case ARGI_TARGETREF:
1526 
1527                 if (ArgOp->Asl.ParseOpcode == PARSEOP_ZERO)
1528                 {
1529                     /* ZERO is the placeholder for "don't store result" */
1530 
1531                     ThisNodeBtype = RequiredBtypes;
1532                     break;
1533                 }
1534 
1535                 if (ArgOp->Asl.ParseOpcode == PARSEOP_INTEGER)
1536                 {
1537                     /*
1538                      * This is the case where an original reference to a resource
1539                      * descriptor field has been replaced by an (Integer) offset.
1540                      * These named fields are supported at compile-time only;
1541                      * the names are not passed to the interpreter (via the AML).
1542                      */
1543                     if ((ArgOp->Asl.Node->Type == ACPI_TYPE_LOCAL_RESOURCE_FIELD) ||
1544                         (ArgOp->Asl.Node->Type == ACPI_TYPE_LOCAL_RESOURCE))
1545                     {
1546                         AslError (ASL_ERROR, ASL_MSG_RESOURCE_FIELD, ArgOp, NULL);
1547                     }
1548                     else
1549                     {
1550                         AslError (ASL_ERROR, ASL_MSG_INVALID_TYPE, ArgOp, NULL);
1551                     }
1552                     break;
1553                 }
1554 
1555                 if ((ArgOp->Asl.ParseOpcode == PARSEOP_METHODCALL) ||
1556                     (ArgOp->Asl.ParseOpcode == PARSEOP_DEREFOF))
1557                 {
1558                     break;
1559                 }
1560 
1561                 ThisNodeBtype = RequiredBtypes;
1562                 break;
1563 
1564 
1565             case ARGI_REFERENCE:            /* References */
1566             case ARGI_INTEGER_REF:
1567             case ARGI_OBJECT_REF:
1568             case ARGI_DEVICE_REF:
1569 
1570                 switch (ArgOp->Asl.ParseOpcode)
1571                 {
1572                 case PARSEOP_LOCAL0:
1573                 case PARSEOP_LOCAL1:
1574                 case PARSEOP_LOCAL2:
1575                 case PARSEOP_LOCAL3:
1576                 case PARSEOP_LOCAL4:
1577                 case PARSEOP_LOCAL5:
1578                 case PARSEOP_LOCAL6:
1579                 case PARSEOP_LOCAL7:
1580 
1581                     /* TBD: implement analysis of current value (type) of the local */
1582                     /* For now, just treat any local as a typematch */
1583 
1584                     /*ThisNodeBtype = RequiredBtypes;*/
1585                     break;
1586 
1587                 case PARSEOP_ARG0:
1588                 case PARSEOP_ARG1:
1589                 case PARSEOP_ARG2:
1590                 case PARSEOP_ARG3:
1591                 case PARSEOP_ARG4:
1592                 case PARSEOP_ARG5:
1593                 case PARSEOP_ARG6:
1594 
1595                     /* Hard to analyze argument types, sow we won't */
1596                     /* For now, just treat any arg as a typematch */
1597 
1598                     /* ThisNodeBtype = RequiredBtypes; */
1599                     break;
1600 
1601                 case PARSEOP_DEBUG:
1602                     break;
1603 
1604                 case PARSEOP_REFOF:
1605                 case PARSEOP_INDEX:
1606                 default:
1607                     break;
1608 
1609                 }
1610                 break;
1611 
1612             case ARGI_INTEGER:
1613             default:
1614                 break;
1615             }
1616 
1617 
1618             CommonBtypes = ThisNodeBtype & RequiredBtypes;
1619 
1620             if (ArgOp->Asl.ParseOpcode == PARSEOP_METHODCALL)
1621             {
1622                 /* Check a method call for a valid return value */
1623 
1624                 AnCheckMethodReturnValue (Op, OpInfo, ArgOp, RequiredBtypes, ThisNodeBtype);
1625             }
1626 
1627             /*
1628              * Now check if the actual type(s) match at least one
1629              * bit to the required type
1630              */
1631             else if (!CommonBtypes)
1632             {
1633                 /* No match -- this is a type mismatch error */
1634 
1635                 AnFormatBtype (StringBuffer, ThisNodeBtype);
1636                 AnFormatBtype (StringBuffer2, RequiredBtypes);
1637 
1638                 sprintf (MsgBuffer, "[%s] found, %s operator requires [%s]",
1639                             StringBuffer, OpInfo->Name, StringBuffer2);
1640 
1641                 AslError (ASL_ERROR, ASL_MSG_INVALID_TYPE, ArgOp, MsgBuffer);
1642             }
1643 
1644         NextArgument:
1645             ArgOp = ArgOp->Asl.Next;
1646             INCREMENT_ARG_LIST (RuntimeArgTypes2);
1647         }
1648         break;
1649 
1650     default:
1651         break;
1652     }
1653 
1654     return (AE_OK);
1655 }
1656 
1657 
1658 /*******************************************************************************
1659  *
1660  * FUNCTION:    AnOtherSemanticAnalysisWalkBegin
1661  *
1662  * PARAMETERS:  ASL_WALK_CALLBACK
1663  *
1664  * RETURN:      Status
1665  *
1666  * DESCRIPTION: Descending callback for the analysis walk.  Check methods for :
1667  *              1) Initialized local variables
1668  *              2) Valid arguments
1669  *              3) Return types
1670  *
1671  ******************************************************************************/
1672 
1673 ACPI_STATUS
1674 AnOtherSemanticAnalysisWalkBegin (
1675     ACPI_PARSE_OBJECT       *Op,
1676     UINT32                  Level,
1677     void                    *Context)
1678 {
1679 
1680     return AE_OK;
1681 }
1682 
1683 
1684 /*******************************************************************************
1685  *
1686  * FUNCTION:    AnOtherSemanticAnalysisWalkEnd
1687  *
1688  * PARAMETERS:  ASL_WALK_CALLBACK
1689  *
1690  * RETURN:      Status
1691  *
1692  * DESCRIPTION: Ascending callback for analysis walk.  Complete method
1693  *              return analysis.
1694  *
1695  ******************************************************************************/
1696 
1697 ACPI_STATUS
1698 AnOtherSemanticAnalysisWalkEnd (
1699     ACPI_PARSE_OBJECT       *Op,
1700     UINT32                  Level,
1701     void                    *Context)
1702 {
1703 
1704     return AE_OK;
1705 
1706 }
1707