xref: /freebsd/sys/contrib/dev/acpica/compiler/aslanalyze.c (revision 7660b554bc59a07be0431c17e0e33815818baa69)
1 
2 /******************************************************************************
3  *
4  * Module Name: aslanalyze.c - check for semantic errors
5  *              $Revision: 77 $
6  *
7  *****************************************************************************/
8 
9 /******************************************************************************
10  *
11  * 1. Copyright Notice
12  *
13  * Some or all of this work - Copyright (c) 1999 - 2003, 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_DEVICE:
894     case PARSEOP_EVENT:
895     case PARSEOP_MUTEX:
896     case PARSEOP_OPERATIONREGION:
897     case PARSEOP_POWERRESOURCE:
898     case PARSEOP_PROCESSOR:
899     case PARSEOP_THERMALZONE:
900 
901         /*
902          * The first operand is a name to be created in the namespace.
903          * Check against the reserved list.
904          */
905         i = AnCheckForReservedName (Op, Op->Asl.NameSeg);
906         if (i < ACPI_VALID_RESERVED_NAME_MAX)
907         {
908             AslError (ASL_ERROR, ASL_MSG_RESERVED_USE, Op, Op->Asl.ExternalName);
909         }
910         break;
911 
912 
913     case PARSEOP_NAME:
914 
915         i = AnCheckForReservedName (Op, Op->Asl.NameSeg);
916         if (i < ACPI_VALID_RESERVED_NAME_MAX)
917         {
918             if (ReservedMethods[i].NumArguments > 0)
919             {
920                 /*
921                  * This reserved name must be a control method because
922                  * it must have arguments
923                  */
924                 AslError (ASL_ERROR, ASL_MSG_RESERVED_METHOD, Op, "with arguments");
925             }
926 
927             /*
928              * Typechecking for _HID
929              */
930             else if (!ACPI_STRCMP (METHOD_NAME__HID, ReservedMethods[i].Name))
931             {
932                 /* Examine the second operand to typecheck it */
933 
934                 Next = Op->Asl.Child->Asl.Next;
935 
936                 if ((Next->Asl.ParseOpcode != PARSEOP_INTEGER) &&
937                     (Next->Asl.ParseOpcode != PARSEOP_STRING_LITERAL))
938                 {
939                     /* _HID must be a string or an integer */
940 
941                     AslError (ASL_ERROR, ASL_MSG_RESERVED_OPERAND_TYPE, Next, "String or Integer");
942                 }
943 
944                 if (Next->Asl.ParseOpcode == PARSEOP_STRING_LITERAL)
945                 {
946                     /*
947                      * _HID is a string, all characters must be alphanumeric.
948                      * One of the things we want to catch here is the use of
949                      * a leading asterisk in the string.
950                      */
951                     for (i = 0; Next->Asl.Value.String[i]; i++)
952                     {
953                         if (!isalnum (Next->Asl.Value.String[i]))
954                         {
955                             AslError (ASL_ERROR, ASL_MSG_ALPHANUMERIC_STRING, Next, Next->Asl.Value.String);
956                             break;
957                         }
958                     }
959                 }
960             }
961         }
962 
963         break;
964 
965 
966     default:
967         break;
968     }
969 
970     return AE_OK;
971 }
972 
973 
974 /*******************************************************************************
975  *
976  * FUNCTION:    AnLastStatementIsReturn
977  *
978  * PARAMETERS:  Op            - A method parse node
979  *
980  * RETURN:      TRUE if last statement is an ASL RETURN.  False otherwise
981  *
982  * DESCRIPTION: Walk down the list of top level statements within a method
983  *              to find the last one.  Check if that last statement is in
984  *              fact a RETURN statement.
985  *
986  ******************************************************************************/
987 
988 BOOLEAN
989 AnLastStatementIsReturn (
990     ACPI_PARSE_OBJECT       *Op)
991 {
992     ACPI_PARSE_OBJECT       *Next;
993 
994 
995     /*
996      * Check if last statement is a return
997      */
998     Next = ASL_GET_CHILD_NODE (Op);
999     while (Next)
1000     {
1001         if ((!Next->Asl.Next) &&
1002             (Next->Asl.ParseOpcode == PARSEOP_RETURN))
1003         {
1004             return TRUE;
1005         }
1006 
1007         Next = ASL_GET_PEER_NODE (Next);
1008     }
1009 
1010     return FALSE;
1011 }
1012 
1013 
1014 /*******************************************************************************
1015  *
1016  * FUNCTION:    AnMethodAnalysisWalkEnd
1017  *
1018  * PARAMETERS:  ASL_WALK_CALLBACK
1019  *
1020  * RETURN:      Status
1021  *
1022  * DESCRIPTION: Ascending callback for analysis walk.  Complete method
1023  *              return analysis.
1024  *
1025  ******************************************************************************/
1026 
1027 ACPI_STATUS
1028 AnMethodAnalysisWalkEnd (
1029     ACPI_PARSE_OBJECT       *Op,
1030     UINT32                  Level,
1031     void                    *Context)
1032 {
1033     ASL_ANALYSIS_WALK_INFO  *WalkInfo = (ASL_ANALYSIS_WALK_INFO *) Context;
1034     ASL_METHOD_INFO         *MethodInfo = WalkInfo->MethodStack;
1035 
1036 
1037     switch (Op->Asl.ParseOpcode)
1038     {
1039     case PARSEOP_METHOD:
1040     case PARSEOP_RETURN:
1041         if (!MethodInfo)
1042         {
1043             printf ("No method info for method! [%s]\n", Op->Asl.Namepath);
1044             AslError (ASL_ERROR, ASL_MSG_COMPILER_INTERNAL, Op, "No method info for this method");
1045             CmCleanupAndExit ();
1046             return (AE_AML_INTERNAL);
1047         }
1048         break;
1049 
1050     default:
1051         break;
1052     }
1053 
1054     switch (Op->Asl.ParseOpcode)
1055     {
1056     case PARSEOP_METHOD:
1057 
1058         WalkInfo->MethodStack = MethodInfo->Next;
1059 
1060         /*
1061          * Check if there is no return statement at the end of the
1062          * method AND we can actually get there -- i.e., the execution
1063          * of the method can possibly terminate without a return statement.
1064          */
1065         if ((!AnLastStatementIsReturn (Op)) &&
1066             (!(Op->Asl.CompileFlags & NODE_HAS_NO_EXIT)))
1067         {
1068             /*
1069              * No return statement, and execution can possibly exit
1070              * via this path.  This is equivalent to Return ()
1071              */
1072             MethodInfo->NumReturnNoValue++;
1073         }
1074 
1075         /*
1076          * Check for case where some return statements have a return value
1077          * and some do not.  Exit without a return statement is a return with
1078          * no value
1079          */
1080         if (MethodInfo->NumReturnNoValue &&
1081             MethodInfo->NumReturnWithValue)
1082         {
1083             AslError (ASL_WARNING, ASL_MSG_RETURN_TYPES, Op, Op->Asl.ExternalName);
1084         }
1085 
1086         /*
1087          * If there are any RETURN() statements with no value, or there is a
1088          * control path that allows the method to exit without a return value,
1089          * we mark the method as a method that does not return a value.  This
1090          * knowledge can be used to check method invocations that expect a
1091          * returned value.
1092          */
1093         if (MethodInfo->NumReturnNoValue)
1094         {
1095             if (MethodInfo->NumReturnWithValue)
1096             {
1097                 Op->Asl.CompileFlags |= NODE_METHOD_SOME_NO_RETVAL;
1098             }
1099             else
1100             {
1101                 Op->Asl.CompileFlags |= NODE_METHOD_NO_RETVAL;
1102             }
1103         }
1104 
1105         /*
1106          * Check predefined method names for correct return behavior
1107          * and correct number of arguments
1108          */
1109         AnCheckForReservedMethod (Op, MethodInfo);
1110         ACPI_MEM_FREE (MethodInfo);
1111         break;
1112 
1113 
1114     case PARSEOP_RETURN:
1115 
1116         /*
1117          * The parent block does not "exit" and continue execution -- the
1118          * method is terminated here with the Return() statement.
1119          */
1120         Op->Asl.Parent->Asl.CompileFlags |= NODE_HAS_NO_EXIT;
1121         Op->Asl.ParentMethod = MethodInfo->Op;      /* Used in the "typing" pass later */
1122 
1123         /*
1124          * If there is a peer node after the return statement, then this
1125          * node is unreachable code -- i.e., it won't be executed because of the
1126          * preceeding Return() statement.
1127          */
1128         if (Op->Asl.Next)
1129         {
1130             AslError (ASL_WARNING, ASL_MSG_UNREACHABLE_CODE, Op->Asl.Next, NULL);
1131         }
1132         break;
1133 
1134 
1135     case PARSEOP_IF:
1136 
1137         if ((Op->Asl.CompileFlags & NODE_HAS_NO_EXIT) &&
1138             (Op->Asl.Next) &&
1139             (Op->Asl.Next->Asl.ParseOpcode == PARSEOP_ELSE))
1140         {
1141             /*
1142              * This IF has a corresponding ELSE.  The IF block has no exit,
1143              * (it contains an unconditional Return)
1144              * mark the ELSE block to remember this fact.
1145              */
1146             Op->Asl.Next->Asl.CompileFlags |= NODE_IF_HAS_NO_EXIT;
1147         }
1148         break;
1149 
1150 
1151     case PARSEOP_ELSE:
1152 
1153         if ((Op->Asl.CompileFlags & NODE_HAS_NO_EXIT) &&
1154             (Op->Asl.CompileFlags & NODE_IF_HAS_NO_EXIT))
1155         {
1156             /*
1157              * This ELSE block has no exit and the corresponding IF block
1158              * has no exit either.  Therefore, the parent node has no exit.
1159              */
1160             Op->Asl.Parent->Asl.CompileFlags |= NODE_HAS_NO_EXIT;
1161         }
1162         break;
1163 
1164 
1165     default:
1166 
1167         if ((Op->Asl.CompileFlags & NODE_HAS_NO_EXIT) &&
1168             (Op->Asl.Parent))
1169         {
1170             /* If this node has no exit, then the parent has no exit either */
1171 
1172             Op->Asl.Parent->Asl.CompileFlags |= NODE_HAS_NO_EXIT;
1173         }
1174         break;
1175     }
1176 
1177     return AE_OK;
1178 }
1179 
1180 
1181 /*******************************************************************************
1182  *
1183  * FUNCTION:    AnMethodTypingWalkBegin
1184  *
1185  * PARAMETERS:  ASL_WALK_CALLBACK
1186  *
1187  * RETURN:      Status
1188  *
1189  * DESCRIPTION: Descending callback for the typing walk.
1190  *
1191  ******************************************************************************/
1192 
1193 ACPI_STATUS
1194 AnMethodTypingWalkBegin (
1195     ACPI_PARSE_OBJECT       *Op,
1196     UINT32                  Level,
1197     void                    *Context)
1198 {
1199 
1200     return AE_OK;
1201 }
1202 
1203 
1204 /*******************************************************************************
1205  *
1206  * FUNCTION:    AnMethodTypingWalkEnd
1207  *
1208  * PARAMETERS:  ASL_WALK_CALLBACK
1209  *
1210  * RETURN:      Status
1211  *
1212  * DESCRIPTION: Ascending callback for typing walk.  Complete method
1213  *              return analysis.  Check methods for :
1214  *              1) Initialized local variables
1215  *              2) Valid arguments
1216  *              3) Return types
1217  *
1218  ******************************************************************************/
1219 
1220 ACPI_STATUS
1221 AnMethodTypingWalkEnd (
1222     ACPI_PARSE_OBJECT       *Op,
1223     UINT32                  Level,
1224     void                    *Context)
1225 {
1226     UINT32                  ThisNodeBtype;
1227 
1228 
1229     switch (Op->Asl.ParseOpcode)
1230     {
1231     case PARSEOP_METHOD:
1232 
1233         Op->Asl.CompileFlags |= NODE_METHOD_TYPED;
1234         break;
1235 
1236     case PARSEOP_RETURN:
1237 
1238         if ((Op->Asl.Child) &&
1239             (Op->Asl.Child->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG))
1240         {
1241             ThisNodeBtype = AnGetBtype (Op->Asl.Child);
1242 
1243             if ((Op->Asl.Child->Asl.ParseOpcode == PARSEOP_METHODCALL) &&
1244                 (ThisNodeBtype == (ACPI_UINT32_MAX -1)))
1245             {
1246                 /*
1247                  * The method is untyped at this time (typically a forward reference).
1248                  * We must recursively type the method here
1249                  */
1250                 TrWalkParseTree (ACPI_CAST_PTR (ACPI_PARSE_OBJECT, Op->Asl.Child->Asl.Node->Object),
1251                         ASL_WALK_VISIT_TWICE, AnMethodTypingWalkBegin,
1252                         AnMethodTypingWalkEnd, NULL);
1253 
1254                 ThisNodeBtype = AnGetBtype (Op->Asl.Child);
1255             }
1256 
1257             /* Returns a value, get it's type */
1258 
1259             if (Op->Asl.ParentMethod)
1260             {
1261                 Op->Asl.ParentMethod->Asl.AcpiBtype |= ThisNodeBtype;
1262             }
1263         }
1264         break;
1265 
1266     default:
1267         break;
1268     }
1269 
1270     return AE_OK;
1271 }
1272 
1273 
1274 /*******************************************************************************
1275  *
1276  * FUNCTION:    AnCheckMethodReturnValue
1277  *
1278  * PARAMETERS:  Op                  - Parent
1279  *              OpInfo              - Parent info
1280  *              ArgOp               - Method invocation op
1281  *              RequiredBtypes      - What caller requires
1282  *              ThisNodeBtype       - What this node returns (if anything)
1283  *
1284  * RETURN:      None
1285  *
1286  * DESCRIPTION: Check a method invocation for 1) A return value and if it does
1287  *              in fact return a value, 2) check the type of the return value.
1288  *
1289  ******************************************************************************/
1290 
1291 void
1292 AnCheckMethodReturnValue (
1293     ACPI_PARSE_OBJECT       *Op,
1294     const ACPI_OPCODE_INFO  *OpInfo,
1295     ACPI_PARSE_OBJECT       *ArgOp,
1296     UINT32                  RequiredBtypes,
1297     UINT32                  ThisNodeBtype)
1298 {
1299     ACPI_PARSE_OBJECT       *OwningOp;
1300     ACPI_NAMESPACE_NODE     *Node;
1301 
1302 
1303     Node = ArgOp->Asl.Node;
1304 
1305 
1306     /* Examine the parent op of this method */
1307 
1308     OwningOp = ACPI_CAST_PTR (ACPI_PARSE_OBJECT, Node->Object);
1309     if (OwningOp->Asl.CompileFlags & NODE_METHOD_NO_RETVAL)
1310     {
1311         /*
1312          * Method NEVER returns a value
1313          */
1314         AslError (ASL_ERROR, ASL_MSG_NO_RETVAL, Op, Op->Asl.ExternalName);
1315     }
1316     else if (OwningOp->Asl.CompileFlags & NODE_METHOD_SOME_NO_RETVAL)
1317     {
1318         /*
1319          * Method SOMETIMES returns a value, SOMETIMES not
1320          */
1321         AslError (ASL_WARNING, ASL_MSG_SOME_NO_RETVAL, Op, Op->Asl.ExternalName);
1322     }
1323     else if (!(ThisNodeBtype & RequiredBtypes))
1324     {
1325         /*
1326          * Method returns a value, but the type is wrong
1327          */
1328         AnFormatBtype (StringBuffer, ThisNodeBtype);
1329         AnFormatBtype (StringBuffer2, RequiredBtypes);
1330 
1331 
1332         /*
1333          * The case where the method does not return any value at all
1334          * was already handled in the namespace cross reference
1335          * -- Only issue an error if the method in fact returns a value,
1336          * but it is of the wrong type
1337          */
1338         if (ThisNodeBtype != 0)
1339         {
1340             sprintf (MsgBuffer, "Method returns [%s], %s operator requires [%s]",
1341                         StringBuffer, OpInfo->Name, StringBuffer2);
1342 
1343             AslError (ASL_ERROR, ASL_MSG_INVALID_TYPE, ArgOp, MsgBuffer);
1344         }
1345     }
1346 }
1347 
1348 
1349 /*******************************************************************************
1350  *
1351  * FUNCTION:    AnOperandTypecheckWalkBegin
1352  *
1353  * PARAMETERS:  ASL_WALK_CALLBACK
1354  *
1355  * RETURN:      Status
1356  *
1357  * DESCRIPTION: Descending callback for the analysis walk.  Check methods for :
1358  *              1) Initialized local variables
1359  *              2) Valid arguments
1360  *              3) Return types
1361  *
1362  ******************************************************************************/
1363 
1364 ACPI_STATUS
1365 AnOperandTypecheckWalkBegin (
1366     ACPI_PARSE_OBJECT       *Op,
1367     UINT32                  Level,
1368     void                    *Context)
1369 {
1370 
1371     return AE_OK;
1372 }
1373 
1374 
1375 /*******************************************************************************
1376  *
1377  * FUNCTION:    AnOperandTypecheckWalkEnd
1378  *
1379  * PARAMETERS:  ASL_WALK_CALLBACK
1380  *
1381  * RETURN:      Status
1382  *
1383  * DESCRIPTION: Ascending callback for analysis walk.  Complete method
1384  *              return analysis.
1385  *
1386  ******************************************************************************/
1387 
1388 ACPI_STATUS
1389 AnOperandTypecheckWalkEnd (
1390     ACPI_PARSE_OBJECT       *Op,
1391     UINT32                  Level,
1392     void                    *Context)
1393 {
1394     const ACPI_OPCODE_INFO  *OpInfo;
1395     UINT32                  RuntimeArgTypes;
1396     UINT32                  RuntimeArgTypes2;
1397     UINT32                  RequiredBtypes;
1398     UINT32                  ThisNodeBtype;
1399     UINT32                  CommonBtypes;
1400     UINT32                  OpcodeClass;
1401     ACPI_PARSE_OBJECT       *ArgOp;
1402     UINT32                  ArgType;
1403 
1404 
1405     switch (Op->Asl.AmlOpcode)
1406     {
1407     case AML_RAW_DATA_BYTE:
1408     case AML_RAW_DATA_WORD:
1409     case AML_RAW_DATA_DWORD:
1410     case AML_RAW_DATA_QWORD:
1411     case AML_RAW_DATA_BUFFER:
1412     case AML_RAW_DATA_CHAIN:
1413     case AML_PACKAGE_LENGTH:
1414     case AML_UNASSIGNED_OPCODE:
1415     case AML_DEFAULT_ARG_OP:
1416 
1417         /* Ignore the internal (compiler-only) AML opcodes */
1418 
1419         return (AE_OK);
1420 
1421     default:
1422         break;
1423     }
1424 
1425     OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode);
1426     if (!OpInfo)
1427     {
1428         return (AE_OK);
1429     }
1430 
1431     ArgOp           = Op->Asl.Child;
1432     RuntimeArgTypes = OpInfo->RuntimeArgs;
1433     OpcodeClass     = OpInfo->Class;
1434 
1435 
1436     /*
1437      * Special case for control opcodes IF/RETURN/WHILE since they
1438      * have no runtime arg list (at this time)
1439      */
1440     switch (Op->Asl.AmlOpcode)
1441     {
1442     case AML_IF_OP:
1443     case AML_WHILE_OP:
1444     case AML_RETURN_OP:
1445 
1446         if (ArgOp->Asl.ParseOpcode == PARSEOP_METHODCALL)
1447         {
1448             /* The lone arg is a method call, check it */
1449 
1450             RequiredBtypes = AnMapArgTypeToBtype (ARGI_INTEGER);
1451             if (Op->Asl.AmlOpcode == AML_RETURN_OP)
1452             {
1453                 RequiredBtypes = 0xFFFFFFFF;
1454             }
1455 
1456             ThisNodeBtype = AnGetBtype (ArgOp);
1457             if (ThisNodeBtype == ACPI_UINT32_MAX)
1458             {
1459                 return (AE_OK);
1460             }
1461             AnCheckMethodReturnValue (Op, OpInfo, ArgOp, RequiredBtypes, ThisNodeBtype);
1462         }
1463         return (AE_OK);
1464 
1465     default:
1466         break;
1467     }
1468 
1469     /* Ignore the non-executable opcodes */
1470 
1471     if (RuntimeArgTypes == ARGI_INVALID_OPCODE)
1472     {
1473         return (AE_OK);
1474     }
1475 
1476     switch (OpcodeClass)
1477     {
1478     case AML_CLASS_EXECUTE:
1479     case AML_CLASS_CREATE:
1480     case AML_CLASS_CONTROL:
1481     case AML_CLASS_RETURN_VALUE:
1482 
1483         /* TBD: Change class or fix typechecking for these */
1484 
1485         if ((Op->Asl.AmlOpcode == AML_BUFFER_OP)        ||
1486             (Op->Asl.AmlOpcode == AML_PACKAGE_OP)       ||
1487             (Op->Asl.AmlOpcode == AML_VAR_PACKAGE_OP))
1488         {
1489             break;
1490         }
1491 
1492         /* Reverse the runtime argument list */
1493 
1494         RuntimeArgTypes2 = 0;
1495         while ((ArgType = GET_CURRENT_ARG_TYPE (RuntimeArgTypes)))
1496         {
1497             RuntimeArgTypes2 <<= ARG_TYPE_WIDTH;
1498             RuntimeArgTypes2 |= ArgType;
1499             INCREMENT_ARG_LIST (RuntimeArgTypes);
1500         }
1501 
1502         while ((ArgType = GET_CURRENT_ARG_TYPE (RuntimeArgTypes2)))
1503         {
1504             RequiredBtypes = AnMapArgTypeToBtype (ArgType);
1505 
1506             ThisNodeBtype = AnGetBtype (ArgOp);
1507             if (ThisNodeBtype == ACPI_UINT32_MAX)
1508             {
1509                 goto NextArgument;
1510             }
1511 
1512             /* Examine the arg based on the required type of the arg */
1513 
1514             switch (ArgType)
1515             {
1516             case ARGI_TARGETREF:
1517 
1518                 if (ArgOp->Asl.ParseOpcode == PARSEOP_ZERO)
1519                 {
1520                     /* ZERO is the placeholder for "don't store result" */
1521 
1522                     ThisNodeBtype = RequiredBtypes;
1523                     break;
1524                 }
1525 
1526                 if (ArgOp->Asl.ParseOpcode == PARSEOP_INTEGER)
1527                 {
1528                     /*
1529                      * This is the case where an original reference to a resource
1530                      * descriptor field has been replaced by an (Integer) offset.
1531                      * These named fields are supported at compile-time only;
1532                      * the names are not passed to the interpreter (via the AML).
1533                      */
1534                     if ((ArgOp->Asl.Node->Type == ACPI_TYPE_LOCAL_RESOURCE_FIELD) ||
1535                         (ArgOp->Asl.Node->Type == ACPI_TYPE_LOCAL_RESOURCE))
1536                     {
1537                         AslError (ASL_ERROR, ASL_MSG_RESOURCE_FIELD, ArgOp, NULL);
1538                     }
1539                     else
1540                     {
1541                         AslError (ASL_ERROR, ASL_MSG_INVALID_TYPE, ArgOp, NULL);
1542                     }
1543                     break;
1544                 }
1545 
1546                 if ((ArgOp->Asl.ParseOpcode == PARSEOP_METHODCALL) ||
1547                     (ArgOp->Asl.ParseOpcode == PARSEOP_DEREFOF))
1548                 {
1549                     break;
1550                 }
1551 
1552                 ThisNodeBtype = RequiredBtypes;
1553                 break;
1554 
1555 
1556             case ARGI_REFERENCE:            /* References */
1557             case ARGI_INTEGER_REF:
1558             case ARGI_OBJECT_REF:
1559             case ARGI_DEVICE_REF:
1560 
1561                 switch (ArgOp->Asl.ParseOpcode)
1562                 {
1563                 case PARSEOP_LOCAL0:
1564                 case PARSEOP_LOCAL1:
1565                 case PARSEOP_LOCAL2:
1566                 case PARSEOP_LOCAL3:
1567                 case PARSEOP_LOCAL4:
1568                 case PARSEOP_LOCAL5:
1569                 case PARSEOP_LOCAL6:
1570                 case PARSEOP_LOCAL7:
1571 
1572                     /* TBD: implement analysis of current value (type) of the local */
1573                     /* For now, just treat any local as a typematch */
1574 
1575                     /*ThisNodeBtype = RequiredBtypes;*/
1576                     break;
1577 
1578                 case PARSEOP_ARG0:
1579                 case PARSEOP_ARG1:
1580                 case PARSEOP_ARG2:
1581                 case PARSEOP_ARG3:
1582                 case PARSEOP_ARG4:
1583                 case PARSEOP_ARG5:
1584                 case PARSEOP_ARG6:
1585 
1586                     /* Hard to analyze argument types, sow we won't */
1587                     /* For now, just treat any arg as a typematch */
1588 
1589                     /* ThisNodeBtype = RequiredBtypes; */
1590                     break;
1591 
1592                 case PARSEOP_DEBUG:
1593                     break;
1594 
1595                 case PARSEOP_REFOF:
1596                 case PARSEOP_INDEX:
1597                 default:
1598                     break;
1599 
1600                 }
1601                 break;
1602 
1603             case ARGI_INTEGER:
1604             default:
1605                 break;
1606             }
1607 
1608 
1609             CommonBtypes = ThisNodeBtype & RequiredBtypes;
1610 
1611             if (ArgOp->Asl.ParseOpcode == PARSEOP_METHODCALL)
1612             {
1613                 /* Check a method call for a valid return value */
1614 
1615                 AnCheckMethodReturnValue (Op, OpInfo, ArgOp, RequiredBtypes, ThisNodeBtype);
1616             }
1617 
1618             /*
1619              * Now check if the actual type(s) match at least one
1620              * bit to the required type
1621              */
1622             else if (!CommonBtypes)
1623             {
1624                 /* No match -- this is a type mismatch error */
1625 
1626                 AnFormatBtype (StringBuffer, ThisNodeBtype);
1627                 AnFormatBtype (StringBuffer2, RequiredBtypes);
1628 
1629                 sprintf (MsgBuffer, "[%s] found, %s operator requires [%s]",
1630                             StringBuffer, OpInfo->Name, StringBuffer2);
1631 
1632                 AslError (ASL_ERROR, ASL_MSG_INVALID_TYPE, ArgOp, MsgBuffer);
1633             }
1634 
1635         NextArgument:
1636             ArgOp = ArgOp->Asl.Next;
1637             INCREMENT_ARG_LIST (RuntimeArgTypes2);
1638         }
1639         break;
1640 
1641     default:
1642         break;
1643     }
1644 
1645     return (AE_OK);
1646 }
1647 
1648 
1649 /*******************************************************************************
1650  *
1651  * FUNCTION:    AnOtherSemanticAnalysisWalkBegin
1652  *
1653  * PARAMETERS:  ASL_WALK_CALLBACK
1654  *
1655  * RETURN:      Status
1656  *
1657  * DESCRIPTION: Descending callback for the analysis walk.  Check methods for :
1658  *              1) Initialized local variables
1659  *              2) Valid arguments
1660  *              3) Return types
1661  *
1662  ******************************************************************************/
1663 
1664 ACPI_STATUS
1665 AnOtherSemanticAnalysisWalkBegin (
1666     ACPI_PARSE_OBJECT       *Op,
1667     UINT32                  Level,
1668     void                    *Context)
1669 {
1670 
1671     return AE_OK;
1672 }
1673 
1674 
1675 /*******************************************************************************
1676  *
1677  * FUNCTION:    AnOtherSemanticAnalysisWalkEnd
1678  *
1679  * PARAMETERS:  ASL_WALK_CALLBACK
1680  *
1681  * RETURN:      Status
1682  *
1683  * DESCRIPTION: Ascending callback for analysis walk.  Complete method
1684  *              return analysis.
1685  *
1686  ******************************************************************************/
1687 
1688 ACPI_STATUS
1689 AnOtherSemanticAnalysisWalkEnd (
1690     ACPI_PARSE_OBJECT       *Op,
1691     UINT32                  Level,
1692     void                    *Context)
1693 {
1694 
1695     return AE_OK;
1696 
1697 }
1698