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