aslanalyze.c revision 167802
1118611Snjl
2118611Snjl/******************************************************************************
3118611Snjl *
4118611Snjl * Module Name: aslanalyze.c - check for semantic errors
5167802Sjkim *              $Revision: 1.115 $
6118611Snjl *
7118611Snjl *****************************************************************************/
8118611Snjl
9118611Snjl/******************************************************************************
10118611Snjl *
11118611Snjl * 1. Copyright Notice
12118611Snjl *
13167802Sjkim * Some or all of this work - Copyright (c) 1999 - 2007, Intel Corp.
14118611Snjl * All rights reserved.
15118611Snjl *
16118611Snjl * 2. License
17118611Snjl *
18118611Snjl * 2.1. This is your license from Intel Corp. under its intellectual property
19118611Snjl * rights.  You may have additional license terms from the party that provided
20118611Snjl * you this software, covering your right to use that party's intellectual
21118611Snjl * property rights.
22118611Snjl *
23118611Snjl * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
24118611Snjl * copy of the source code appearing in this file ("Covered Code") an
25118611Snjl * irrevocable, perpetual, worldwide license under Intel's copyrights in the
26118611Snjl * base code distributed originally by Intel ("Original Intel Code") to copy,
27118611Snjl * make derivatives, distribute, use and display any portion of the Covered
28118611Snjl * Code in any form, with the right to sublicense such rights; and
29118611Snjl *
30118611Snjl * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
31118611Snjl * license (with the right to sublicense), under only those claims of Intel
32118611Snjl * patents that are infringed by the Original Intel Code, to make, use, sell,
33118611Snjl * offer to sell, and import the Covered Code and derivative works thereof
34118611Snjl * solely to the minimum extent necessary to exercise the above copyright
35118611Snjl * license, and in no event shall the patent license extend to any additions
36118611Snjl * to or modifications of the Original Intel Code.  No other license or right
37118611Snjl * is granted directly or by implication, estoppel or otherwise;
38118611Snjl *
39118611Snjl * The above copyright and patent license is granted only if the following
40118611Snjl * conditions are met:
41118611Snjl *
42118611Snjl * 3. Conditions
43118611Snjl *
44118611Snjl * 3.1. Redistribution of Source with Rights to Further Distribute Source.
45118611Snjl * Redistribution of source code of any substantial portion of the Covered
46118611Snjl * Code or modification with rights to further distribute source must include
47118611Snjl * the above Copyright Notice, the above License, this list of Conditions,
48118611Snjl * and the following Disclaimer and Export Compliance provision.  In addition,
49118611Snjl * Licensee must cause all Covered Code to which Licensee contributes to
50118611Snjl * contain a file documenting the changes Licensee made to create that Covered
51118611Snjl * Code and the date of any change.  Licensee must include in that file the
52118611Snjl * documentation of any changes made by any predecessor Licensee.  Licensee
53118611Snjl * must include a prominent statement that the modification is derived,
54118611Snjl * directly or indirectly, from Original Intel Code.
55118611Snjl *
56118611Snjl * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
57118611Snjl * Redistribution of source code of any substantial portion of the Covered
58118611Snjl * Code or modification without rights to further distribute source must
59118611Snjl * include the following Disclaimer and Export Compliance provision in the
60118611Snjl * documentation and/or other materials provided with distribution.  In
61118611Snjl * addition, Licensee may not authorize further sublicense of source of any
62118611Snjl * portion of the Covered Code, and must include terms to the effect that the
63118611Snjl * license from Licensee to its licensee is limited to the intellectual
64118611Snjl * property embodied in the software Licensee provides to its licensee, and
65118611Snjl * not to intellectual property embodied in modifications its licensee may
66118611Snjl * make.
67118611Snjl *
68118611Snjl * 3.3. Redistribution of Executable. Redistribution in executable form of any
69118611Snjl * substantial portion of the Covered Code or modification must reproduce the
70118611Snjl * above Copyright Notice, and the following Disclaimer and Export Compliance
71118611Snjl * provision in the documentation and/or other materials provided with the
72118611Snjl * distribution.
73118611Snjl *
74118611Snjl * 3.4. Intel retains all right, title, and interest in and to the Original
75118611Snjl * Intel Code.
76118611Snjl *
77118611Snjl * 3.5. Neither the name Intel nor any other trademark owned or controlled by
78118611Snjl * Intel shall be used in advertising or otherwise to promote the sale, use or
79118611Snjl * other dealings in products derived from or relating to the Covered Code
80118611Snjl * without prior written authorization from Intel.
81118611Snjl *
82118611Snjl * 4. Disclaimer and Export Compliance
83118611Snjl *
84118611Snjl * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
85118611Snjl * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
86118611Snjl * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
87118611Snjl * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
88118611Snjl * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
89118611Snjl * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
90118611Snjl * PARTICULAR PURPOSE.
91118611Snjl *
92118611Snjl * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
93118611Snjl * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
94118611Snjl * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
95118611Snjl * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
96118611Snjl * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
97118611Snjl * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
98118611Snjl * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
99118611Snjl * LIMITED REMEDY.
100118611Snjl *
101118611Snjl * 4.3. Licensee shall not export, either directly or indirectly, any of this
102118611Snjl * software or system incorporating such software without first obtaining any
103118611Snjl * required license or other approval from the U. S. Department of Commerce or
104118611Snjl * any other agency or department of the United States Government.  In the
105118611Snjl * event Licensee exports any such software from the United States or
106118611Snjl * re-exports any such software from a foreign destination, Licensee shall
107118611Snjl * ensure that the distribution and export/re-export of the software is in
108118611Snjl * compliance with all laws, regulations, orders, or other restrictions of the
109118611Snjl * U.S. Export Administration Regulations. Licensee agrees that neither it nor
110118611Snjl * any of its subsidiaries will export/re-export any technical data, process,
111118611Snjl * software, or service, directly or indirectly, to any country for which the
112118611Snjl * United States government or any agency thereof requires an export license,
113118611Snjl * other governmental approval, or letter of assurance, without first obtaining
114118611Snjl * such license, approval or letter.
115118611Snjl *
116118611Snjl *****************************************************************************/
117118611Snjl
118118611Snjl
119151937Sjkim#include <contrib/dev/acpica/compiler/aslcompiler.h>
120118611Snjl#include "aslcompiler.y.h"
121151937Sjkim#include <contrib/dev/acpica/acparser.h>
122151937Sjkim#include <contrib/dev/acpica/amlcode.h>
123118611Snjl
124118611Snjl#include <ctype.h>
125118611Snjl
126118611Snjl#define _COMPONENT          ACPI_COMPILER
127118611Snjl        ACPI_MODULE_NAME    ("aslanalyze")
128118611Snjl
129151937Sjkim/* Local prototypes */
130118611Snjl
131151937Sjkimstatic UINT32
132151937SjkimAnMapArgTypeToBtype (
133151937Sjkim    UINT32                  ArgType);
134151937Sjkim
135151937Sjkimstatic UINT32
136151937SjkimAnMapEtypeToBtype (
137151937Sjkim    UINT32                  Etype);
138151937Sjkim
139151937Sjkimstatic void
140151937SjkimAnFormatBtype (
141151937Sjkim    char                    *Buffer,
142151937Sjkim    UINT32                  Btype);
143151937Sjkim
144151937Sjkimstatic UINT32
145151937SjkimAnGetBtype (
146151937Sjkim    ACPI_PARSE_OBJECT       *Op);
147151937Sjkim
148151937Sjkimstatic UINT32
149151937SjkimAnCheckForReservedName (
150151937Sjkim    ACPI_PARSE_OBJECT       *Op,
151151937Sjkim    char                    *Name);
152151937Sjkim
153151937Sjkimstatic void
154151937SjkimAnCheckForReservedMethod (
155151937Sjkim    ACPI_PARSE_OBJECT       *Op,
156151937Sjkim    ASL_METHOD_INFO         *MethodInfo);
157151937Sjkim
158151937Sjkimstatic UINT32
159151937SjkimAnMapObjTypeToBtype (
160151937Sjkim    ACPI_PARSE_OBJECT       *Op);
161151937Sjkim
162151937Sjkimstatic BOOLEAN
163151937SjkimAnLastStatementIsReturn (
164151937Sjkim    ACPI_PARSE_OBJECT       *Op);
165151937Sjkim
166151937Sjkimstatic void
167151937SjkimAnCheckMethodReturnValue (
168151937Sjkim    ACPI_PARSE_OBJECT       *Op,
169151937Sjkim    const ACPI_OPCODE_INFO  *OpInfo,
170151937Sjkim    ACPI_PARSE_OBJECT       *ArgOp,
171151937Sjkim    UINT32                  RequiredBtypes,
172151937Sjkim    UINT32                  ThisNodeBtype);
173151937Sjkim
174167802Sjkimstatic BOOLEAN
175167802SjkimAnIsInternalMethod (
176167802Sjkim    ACPI_PARSE_OBJECT       *Op);
177151937Sjkim
178167802Sjkimstatic UINT32
179167802SjkimAnGetInternalMethodReturnType (
180167802Sjkim    ACPI_PARSE_OBJECT       *Op);
181167802Sjkim
182167802Sjkim
183118611Snjl/*******************************************************************************
184118611Snjl *
185167802Sjkim * FUNCTION:    AnIsInternalMethod
186167802Sjkim *
187167802Sjkim * PARAMETERS:  Op              - Current op
188167802Sjkim *
189167802Sjkim * RETURN:      Boolean
190167802Sjkim *
191167802Sjkim * DESCRIPTION: Check for an internal control method.
192167802Sjkim *
193167802Sjkim ******************************************************************************/
194167802Sjkim
195167802Sjkimstatic BOOLEAN
196167802SjkimAnIsInternalMethod (
197167802Sjkim    ACPI_PARSE_OBJECT       *Op)
198167802Sjkim{
199167802Sjkim
200167802Sjkim    if ((!ACPI_STRCMP (Op->Asl.ExternalName, "\\_OSI")) ||
201167802Sjkim        (!ACPI_STRCMP (Op->Asl.ExternalName, "_OSI")))
202167802Sjkim    {
203167802Sjkim        return (TRUE);
204167802Sjkim    }
205167802Sjkim
206167802Sjkim    return (FALSE);
207167802Sjkim}
208167802Sjkim
209167802Sjkim
210167802Sjkim/*******************************************************************************
211167802Sjkim *
212167802Sjkim * FUNCTION:    AnGetInternalMethodReturnType
213167802Sjkim *
214167802Sjkim * PARAMETERS:  Op              - Current op
215167802Sjkim *
216167802Sjkim * RETURN:      Btype
217167802Sjkim *
218167802Sjkim * DESCRIPTION: Get the return type of an internal method
219167802Sjkim *
220167802Sjkim ******************************************************************************/
221167802Sjkim
222167802Sjkimstatic UINT32
223167802SjkimAnGetInternalMethodReturnType (
224167802Sjkim    ACPI_PARSE_OBJECT       *Op)
225167802Sjkim{
226167802Sjkim
227167802Sjkim    if ((!ACPI_STRCMP (Op->Asl.ExternalName, "\\_OSI")) ||
228167802Sjkim        (!ACPI_STRCMP (Op->Asl.ExternalName, "_OSI")))
229167802Sjkim    {
230167802Sjkim        return (ACPI_BTYPE_STRING);
231167802Sjkim    }
232167802Sjkim
233167802Sjkim    return (0);
234167802Sjkim}
235167802Sjkim
236167802Sjkim
237167802Sjkim/*******************************************************************************
238167802Sjkim *
239118611Snjl * FUNCTION:    AnMapArgTypeToBtype
240118611Snjl *
241118611Snjl * PARAMETERS:  ArgType      - The ARGI required type(s) for this argument,
242118611Snjl *                             from the opcode info table
243118611Snjl *
244118611Snjl * RETURN:      The corresponding Bit-encoded types
245118611Snjl *
246118611Snjl * DESCRIPTION: Convert an encoded ARGI required argument type code into a
247167802Sjkim *              bitfield type code. Implements the implicit source conversion
248118611Snjl *              rules.
249118611Snjl *
250118611Snjl ******************************************************************************/
251118611Snjl
252151937Sjkimstatic UINT32
253118611SnjlAnMapArgTypeToBtype (
254118611Snjl    UINT32                  ArgType)
255118611Snjl{
256118611Snjl
257118611Snjl    switch (ArgType)
258118611Snjl    {
259118611Snjl
260118611Snjl    /* Simple types */
261118611Snjl
262118611Snjl    case ARGI_ANYTYPE:
263118611Snjl        return (ACPI_BTYPE_OBJECTS_AND_REFS);
264118611Snjl
265118611Snjl    case ARGI_PACKAGE:
266118611Snjl        return (ACPI_BTYPE_PACKAGE);
267118611Snjl
268118611Snjl    case ARGI_EVENT:
269118611Snjl        return (ACPI_BTYPE_EVENT);
270118611Snjl
271118611Snjl    case ARGI_MUTEX:
272118611Snjl        return (ACPI_BTYPE_MUTEX);
273118611Snjl
274118611Snjl    case ARGI_DDBHANDLE:
275118611Snjl        return (ACPI_BTYPE_DDB_HANDLE);
276118611Snjl
277118611Snjl    /* Interchangeable types */
278118611Snjl    /*
279118611Snjl     * Source conversion rules:
280118611Snjl     * Integer, String, and Buffer are all interchangeable
281118611Snjl     */
282118611Snjl    case ARGI_INTEGER:
283118611Snjl    case ARGI_STRING:
284118611Snjl    case ARGI_BUFFER:
285118611Snjl    case ARGI_BUFFER_OR_STRING:
286118611Snjl    case ARGI_COMPUTEDATA:
287118611Snjl        return (ACPI_BTYPE_COMPUTE_DATA);
288118611Snjl
289118611Snjl    /* References */
290118611Snjl
291118611Snjl    case ARGI_INTEGER_REF:
292118611Snjl        return (ACPI_BTYPE_INTEGER);
293118611Snjl
294118611Snjl    case ARGI_OBJECT_REF:
295118611Snjl        return (ACPI_BTYPE_ALL_OBJECTS);
296118611Snjl
297118611Snjl    case ARGI_DEVICE_REF:
298118611Snjl        return (ACPI_BTYPE_DEVICE_OBJECTS);
299118611Snjl
300118611Snjl    case ARGI_REFERENCE:
301118611Snjl        return (ACPI_BTYPE_REFERENCE);
302118611Snjl
303118611Snjl    case ARGI_TARGETREF:
304118611Snjl    case ARGI_FIXED_TARGET:
305118611Snjl    case ARGI_SIMPLE_TARGET:
306118611Snjl        return (ACPI_BTYPE_OBJECTS_AND_REFS);
307118611Snjl
308118611Snjl    /* Complex types */
309118611Snjl
310118611Snjl    case ARGI_DATAOBJECT:
311118611Snjl
312151937Sjkim        /*
313151937Sjkim         * Buffer, string, package or reference to a Op -
314151937Sjkim         * Used only by SizeOf operator
315151937Sjkim         */
316151937Sjkim        return (ACPI_BTYPE_STRING | ACPI_BTYPE_BUFFER |
317151937Sjkim            ACPI_BTYPE_PACKAGE | ACPI_BTYPE_REFERENCE);
318118611Snjl
319118611Snjl    case ARGI_COMPLEXOBJ:
320118611Snjl
321118611Snjl        /* Buffer, String, or package */
322118611Snjl
323118611Snjl        return (ACPI_BTYPE_STRING | ACPI_BTYPE_BUFFER | ACPI_BTYPE_PACKAGE);
324118611Snjl
325118611Snjl    case ARGI_REF_OR_STRING:
326118611Snjl        return (ACPI_BTYPE_STRING | ACPI_BTYPE_REFERENCE);
327118611Snjl
328167802Sjkim    case ARGI_REGION_OR_BUFFER:
329118611Snjl
330167802Sjkim        /* Used by Load() only. Allow buffers in addition to regions/fields */
331167802Sjkim
332167802Sjkim        return (ACPI_BTYPE_REGION | ACPI_BTYPE_BUFFER | ACPI_BTYPE_FIELD_UNIT);
333167802Sjkim
334151937Sjkim    case ARGI_DATAREFOBJ:
335151937Sjkim        return (ACPI_BTYPE_INTEGER |ACPI_BTYPE_STRING | ACPI_BTYPE_BUFFER |
336151937Sjkim            ACPI_BTYPE_PACKAGE | ACPI_BTYPE_REFERENCE | ACPI_BTYPE_DDB_HANDLE);
337151937Sjkim
338118611Snjl    default:
339118611Snjl        break;
340118611Snjl    }
341118611Snjl
342118611Snjl    return (ACPI_BTYPE_OBJECTS_AND_REFS);
343118611Snjl}
344118611Snjl
345118611Snjl
346118611Snjl/*******************************************************************************
347118611Snjl *
348118611Snjl * FUNCTION:    AnMapEtypeToBtype
349118611Snjl *
350118611Snjl * PARAMETERS:  Etype           - Encoded ACPI Type
351118611Snjl *
352118611Snjl * RETURN:      Btype corresponding to the Etype
353118611Snjl *
354118611Snjl * DESCRIPTION: Convert an encoded ACPI type to a bitfield type applying the
355167802Sjkim *              operand conversion rules. In other words, returns the type(s)
356118611Snjl *              this Etype is implicitly converted to during interpretation.
357118611Snjl *
358118611Snjl ******************************************************************************/
359118611Snjl
360151937Sjkimstatic UINT32
361118611SnjlAnMapEtypeToBtype (
362151937Sjkim    UINT32                  Etype)
363118611Snjl{
364118611Snjl
365118611Snjl
366118611Snjl    if (Etype == ACPI_TYPE_ANY)
367118611Snjl    {
368118611Snjl        return ACPI_BTYPE_OBJECTS_AND_REFS;
369118611Snjl    }
370118611Snjl
371118611Snjl    /* Try the standard ACPI data types */
372118611Snjl
373118611Snjl    if (Etype <= ACPI_TYPE_EXTERNAL_MAX)
374118611Snjl    {
375118611Snjl        /*
376118611Snjl         * This switch statement implements the allowed operand conversion
377118611Snjl         * rules as per the "ASL Data Types" section of the ACPI
378118611Snjl         * specification.
379118611Snjl         */
380118611Snjl        switch (Etype)
381118611Snjl        {
382118611Snjl        case ACPI_TYPE_INTEGER:
383118611Snjl            return (ACPI_BTYPE_COMPUTE_DATA | ACPI_BTYPE_DDB_HANDLE);
384118611Snjl
385118611Snjl        case ACPI_TYPE_STRING:
386118611Snjl        case ACPI_TYPE_BUFFER:
387118611Snjl            return (ACPI_BTYPE_COMPUTE_DATA);
388118611Snjl
389118611Snjl        case ACPI_TYPE_PACKAGE:
390118611Snjl            return (ACPI_BTYPE_PACKAGE);
391118611Snjl
392118611Snjl        case ACPI_TYPE_FIELD_UNIT:
393118611Snjl            return (ACPI_BTYPE_COMPUTE_DATA | ACPI_BTYPE_FIELD_UNIT);
394118611Snjl
395118611Snjl        case ACPI_TYPE_BUFFER_FIELD:
396118611Snjl            return (ACPI_BTYPE_COMPUTE_DATA | ACPI_BTYPE_BUFFER_FIELD);
397118611Snjl
398118611Snjl        case ACPI_TYPE_DDB_HANDLE:
399118611Snjl            return (ACPI_BTYPE_INTEGER | ACPI_BTYPE_DDB_HANDLE);
400118611Snjl
401118611Snjl        case ACPI_BTYPE_DEBUG_OBJECT:
402118611Snjl
403118611Snjl            /* Cannot be used as a source operand */
404118611Snjl
405118611Snjl            return (0);
406118611Snjl
407118611Snjl        default:
408118611Snjl            return (1 << (Etype - 1));
409118611Snjl        }
410118611Snjl    }
411118611Snjl
412118611Snjl    /* Try the internal data types */
413118611Snjl
414118611Snjl    switch (Etype)
415118611Snjl    {
416118611Snjl    case ACPI_TYPE_LOCAL_REGION_FIELD:
417118611Snjl    case ACPI_TYPE_LOCAL_BANK_FIELD:
418118611Snjl    case ACPI_TYPE_LOCAL_INDEX_FIELD:
419118611Snjl
420118611Snjl        /* Named fields can be either Integer/Buffer/String */
421118611Snjl
422118611Snjl        return (ACPI_BTYPE_COMPUTE_DATA | ACPI_BTYPE_FIELD_UNIT);
423118611Snjl
424118611Snjl    case ACPI_TYPE_LOCAL_ALIAS:
425118611Snjl
426118611Snjl        return (ACPI_BTYPE_INTEGER);
427118611Snjl
428118611Snjl
429118611Snjl    case ACPI_TYPE_LOCAL_RESOURCE:
430118611Snjl    case ACPI_TYPE_LOCAL_RESOURCE_FIELD:
431118611Snjl
432118611Snjl        return (ACPI_BTYPE_REFERENCE);
433118611Snjl
434118611Snjl    default:
435118611Snjl        printf ("Unhandled encoded type: %X\n", Etype);
436118611Snjl        return (0);
437118611Snjl    }
438118611Snjl}
439118611Snjl
440118611Snjl
441118611Snjl/*******************************************************************************
442118611Snjl *
443118611Snjl * FUNCTION:    AnFormatBtype
444118611Snjl *
445118611Snjl * PARAMETERS:  Btype               - Bitfield of ACPI types
446118611Snjl *              Buffer              - Where to put the ascii string
447118611Snjl *
448118611Snjl * RETURN:      None.
449118611Snjl *
450118611Snjl * DESCRIPTION: Convert a Btype to a string of ACPI types
451118611Snjl *
452118611Snjl ******************************************************************************/
453118611Snjl
454151937Sjkimstatic void
455118611SnjlAnFormatBtype (
456151937Sjkim    char                    *Buffer,
457151937Sjkim    UINT32                  Btype)
458118611Snjl{
459151937Sjkim    UINT32                  Type;
460151937Sjkim    BOOLEAN                 First = TRUE;
461118611Snjl
462118611Snjl
463118611Snjl    *Buffer = 0;
464118611Snjl
465118611Snjl    if (Btype == 0)
466118611Snjl    {
467118611Snjl        strcat (Buffer, "NoReturnValue");
468118611Snjl        return;
469118611Snjl    }
470118611Snjl
471151937Sjkim    for (Type = 1; Type <= ACPI_TYPE_EXTERNAL_MAX; Type++)
472118611Snjl    {
473118611Snjl        if (Btype & 0x00000001)
474118611Snjl        {
475118611Snjl            if (!First)
476118611Snjl            {
477118611Snjl                strcat (Buffer, "|");
478118611Snjl            }
479118611Snjl            First = FALSE;
480118611Snjl            strcat (Buffer, AcpiUtGetTypeName (Type));
481118611Snjl        }
482118611Snjl        Btype >>= 1;
483118611Snjl    }
484118611Snjl
485118611Snjl    if (Btype & 0x00000001)
486118611Snjl    {
487118611Snjl        if (!First)
488118611Snjl        {
489118611Snjl            strcat (Buffer, "|");
490118611Snjl        }
491118611Snjl        First = FALSE;
492118611Snjl        strcat (Buffer, "Reference");
493118611Snjl    }
494118611Snjl
495118611Snjl    Btype >>= 1;
496118611Snjl    if (Btype & 0x00000001)
497118611Snjl    {
498118611Snjl        if (!First)
499118611Snjl        {
500118611Snjl            strcat (Buffer, "|");
501118611Snjl        }
502118611Snjl        First = FALSE;
503118611Snjl        strcat (Buffer, "Resource");
504118611Snjl    }
505118611Snjl}
506118611Snjl
507118611Snjl
508118611Snjl/*******************************************************************************
509118611Snjl *
510118611Snjl * FUNCTION:    AnGetBtype
511118611Snjl *
512118611Snjl * PARAMETERS:  Op          - Parse node whose type will be returned.
513118611Snjl *
514118611Snjl * RETURN:      The Btype associated with the Op.
515118611Snjl *
516118611Snjl * DESCRIPTION: Get the (bitfield) ACPI type associated with the parse node.
517118611Snjl *              Handles the case where the node is a name or method call and
518118611Snjl *              the actual type must be obtained from the namespace node.
519118611Snjl *
520118611Snjl ******************************************************************************/
521118611Snjl
522151937Sjkimstatic UINT32
523118611SnjlAnGetBtype (
524118611Snjl    ACPI_PARSE_OBJECT       *Op)
525118611Snjl{
526118611Snjl    ACPI_NAMESPACE_NODE     *Node;
527118611Snjl    ACPI_PARSE_OBJECT       *ReferencedNode;
528118611Snjl    UINT32                  ThisNodeBtype = 0;
529118611Snjl
530118611Snjl
531118611Snjl    if ((Op->Asl.ParseOpcode == PARSEOP_NAMESEG)     ||
532118611Snjl        (Op->Asl.ParseOpcode == PARSEOP_NAMESTRING)  ||
533118611Snjl        (Op->Asl.ParseOpcode == PARSEOP_METHODCALL))
534118611Snjl    {
535118611Snjl        Node = Op->Asl.Node;
536118611Snjl        if (!Node)
537118611Snjl        {
538118611Snjl            DbgPrint (ASL_DEBUG_OUTPUT,
539138287Smarks                "No attached Nsnode: [%s] at line %d name [%s], ignoring typecheck\n",
540138287Smarks                Op->Asl.ParseOpName, Op->Asl.LineNumber,
541138287Smarks                Op->Asl.ExternalName);
542118611Snjl            return ACPI_UINT32_MAX;
543118611Snjl        }
544118611Snjl
545118611Snjl        ThisNodeBtype = AnMapEtypeToBtype (Node->Type);
546151937Sjkim        if (!ThisNodeBtype)
547151937Sjkim        {
548167802Sjkim            AslError (ASL_ERROR, ASL_MSG_COMPILER_INTERNAL, Op,
549167802Sjkim                "could not map type");
550151937Sjkim        }
551118611Snjl
552118611Snjl        /*
553118611Snjl         * Since it was a named reference, enable the
554118611Snjl         * reference bit also
555118611Snjl         */
556118611Snjl        ThisNodeBtype |= ACPI_BTYPE_REFERENCE;
557118611Snjl
558118611Snjl        if (Op->Asl.ParseOpcode == PARSEOP_METHODCALL)
559118611Snjl        {
560151937Sjkim            ReferencedNode = Node->Op;
561118611Snjl            if (!ReferencedNode)
562118611Snjl            {
563167802Sjkim                /* Check for an internal method */
564167802Sjkim
565167802Sjkim                if (AnIsInternalMethod (Op))
566167802Sjkim                {
567167802Sjkim                    return (AnGetInternalMethodReturnType (Op));
568167802Sjkim                }
569167802Sjkim
570167802Sjkim                AslError (ASL_ERROR, ASL_MSG_COMPILER_INTERNAL, Op,
571167802Sjkim                    "null Op pointer");
572167802Sjkim                return ACPI_UINT32_MAX;
573118611Snjl            }
574118611Snjl
575118611Snjl            if (ReferencedNode->Asl.CompileFlags & NODE_METHOD_TYPED)
576118611Snjl            {
577118611Snjl                ThisNodeBtype = ReferencedNode->Asl.AcpiBtype;
578118611Snjl            }
579118611Snjl            else
580118611Snjl            {
581118611Snjl                return (ACPI_UINT32_MAX -1);
582118611Snjl            }
583118611Snjl        }
584118611Snjl    }
585118611Snjl    else
586118611Snjl    {
587118611Snjl        ThisNodeBtype = Op->Asl.AcpiBtype;
588118611Snjl    }
589118611Snjl
590118611Snjl    return (ThisNodeBtype);
591118611Snjl}
592118611Snjl
593118611Snjl
594118611Snjl/*******************************************************************************
595118611Snjl *
596118611Snjl * FUNCTION:    AnCheckForReservedName
597118611Snjl *
598118611Snjl * PARAMETERS:  Op              - A parse node
599118611Snjl *              Name            - NameSeg to check
600118611Snjl *
601118611Snjl * RETURN:      None
602118611Snjl *
603118611Snjl * DESCRIPTION: Check a NameSeg against the reserved list.
604118611Snjl *
605118611Snjl ******************************************************************************/
606118611Snjl
607151937Sjkimstatic UINT32
608118611SnjlAnCheckForReservedName (
609118611Snjl    ACPI_PARSE_OBJECT       *Op,
610118611Snjl    char                    *Name)
611118611Snjl{
612118611Snjl    UINT32                  i;
613118611Snjl
614118611Snjl
615118611Snjl    if (Name[0] == 0)
616118611Snjl    {
617151937Sjkim        AcpiOsPrintf ("Found a null name, external = %s\n",
618151937Sjkim            Op->Asl.ExternalName);
619118611Snjl    }
620118611Snjl
621118611Snjl    /* All reserved names are prefixed with a single underscore */
622118611Snjl
623118611Snjl    if (Name[0] != '_')
624118611Snjl    {
625118611Snjl        return (ACPI_NOT_RESERVED_NAME);
626118611Snjl    }
627118611Snjl
628118611Snjl    /* Check for a standard reserved method name */
629118611Snjl
630118611Snjl    for (i = 0; ReservedMethods[i].Name; i++)
631118611Snjl    {
632167802Sjkim        if (ACPI_COMPARE_NAME (Name, ReservedMethods[i].Name))
633118611Snjl        {
634118611Snjl            if (ReservedMethods[i].Flags & ASL_RSVD_SCOPE)
635118611Snjl            {
636151937Sjkim                AslError (ASL_ERROR, ASL_MSG_RESERVED_WORD, Op,
637151937Sjkim                    Op->Asl.ExternalName);
638118611Snjl                return (ACPI_PREDEFINED_NAME);
639118611Snjl            }
640118611Snjl            else if (ReservedMethods[i].Flags & ASL_RSVD_RESOURCE_NAME)
641118611Snjl            {
642151937Sjkim                AslError (ASL_ERROR, ASL_MSG_RESERVED_WORD, Op,
643151937Sjkim                    Op->Asl.ExternalName);
644118611Snjl                return (ACPI_PREDEFINED_NAME);
645118611Snjl            }
646118611Snjl
647118611Snjl            /* Return index into reserved array */
648118611Snjl
649118611Snjl            return i;
650118611Snjl        }
651118611Snjl    }
652118611Snjl
653118611Snjl    /*
654118611Snjl     * Now check for the "special" reserved names --
655118611Snjl     * GPE:  _Lxx
656118611Snjl     * GPE:  _Exx
657118611Snjl     * EC:   _Qxx
658118611Snjl     */
659118611Snjl    if ((Name[1] == 'L') ||
660118611Snjl        (Name[1] == 'E') ||
661118611Snjl        (Name[1] == 'Q'))
662118611Snjl    {
663118611Snjl        /* The next two characters must be hex digits */
664118611Snjl
665118611Snjl        if ((isxdigit (Name[2])) &&
666118611Snjl            (isxdigit (Name[3])))
667118611Snjl        {
668118611Snjl            return (ACPI_EVENT_RESERVED_NAME);
669118611Snjl        }
670118611Snjl    }
671118611Snjl
672118611Snjl
673118611Snjl    /* Check for the names reserved for the compiler itself: _T_x */
674118611Snjl
675118611Snjl    else if ((Op->Asl.ExternalName[1] == 'T') &&
676118611Snjl             (Op->Asl.ExternalName[2] == '_'))
677118611Snjl    {
678138287Smarks        /* Ignore if actually emitted by the compiler */
679138287Smarks
680138287Smarks        if (Op->Asl.CompileFlags & NODE_COMPILER_EMITTED)
681138287Smarks        {
682138287Smarks            return (ACPI_NOT_RESERVED_NAME);
683138287Smarks        }
684138287Smarks
685118611Snjl        AslError (ASL_ERROR, ASL_MSG_RESERVED_WORD, Op, Op->Asl.ExternalName);
686118611Snjl        return (ACPI_COMPILER_RESERVED_NAME);
687118611Snjl    }
688118611Snjl
689118611Snjl    /*
690167802Sjkim     * The name didn't match any of the known reserved names. Flag it as a
691118611Snjl     * warning, since the entire namespace starting with an underscore is
692118611Snjl     * reserved by the ACPI spec.
693118611Snjl     */
694151937Sjkim    AslError (ASL_WARNING, ASL_MSG_UNKNOWN_RESERVED_NAME, Op,
695151937Sjkim        Op->Asl.ExternalName);
696118611Snjl
697118611Snjl    return (ACPI_NOT_RESERVED_NAME);
698118611Snjl}
699118611Snjl
700118611Snjl
701118611Snjl/*******************************************************************************
702118611Snjl *
703118611Snjl * FUNCTION:    AnCheckForReservedMethod
704118611Snjl *
705118611Snjl * PARAMETERS:  Op              - A parse node of type "METHOD".
706118611Snjl *              MethodInfo      - Saved info about this method
707118611Snjl *
708118611Snjl * RETURN:      None
709118611Snjl *
710118611Snjl * DESCRIPTION: If method is a reserved name, check that the number of arguments
711118611Snjl *              and the return type (returns a value or not) is correct.
712118611Snjl *
713118611Snjl ******************************************************************************/
714118611Snjl
715151937Sjkimstatic void
716118611SnjlAnCheckForReservedMethod (
717118611Snjl    ACPI_PARSE_OBJECT       *Op,
718118611Snjl    ASL_METHOD_INFO         *MethodInfo)
719118611Snjl{
720118611Snjl    UINT32                  Index;
721118611Snjl
722118611Snjl
723118611Snjl    /* Check for a match against the reserved name list */
724118611Snjl
725118611Snjl    Index = AnCheckForReservedName (Op, Op->Asl.NameSeg);
726118611Snjl
727118611Snjl    switch (Index)
728118611Snjl    {
729118611Snjl    case ACPI_NOT_RESERVED_NAME:
730118611Snjl    case ACPI_PREDEFINED_NAME:
731118611Snjl    case ACPI_COMPILER_RESERVED_NAME:
732118611Snjl
733118611Snjl        /* Just return, nothing to do */
734118611Snjl        break;
735118611Snjl
736118611Snjl
737118611Snjl    case ACPI_EVENT_RESERVED_NAME:
738118611Snjl
739118611Snjl        Gbl_ReservedMethods++;
740118611Snjl
741118611Snjl        /* NumArguments must be zero for all _Lxx, _Exx, and _Qxx methods */
742118611Snjl
743118611Snjl        if (MethodInfo->NumArguments != 0)
744118611Snjl        {
745167802Sjkim            sprintf (MsgBuffer, "%s requires %d",
746118611Snjl                        Op->Asl.ExternalName, 0);
747118611Snjl
748118611Snjl            AslError (ASL_WARNING, ASL_MSG_RESERVED_ARG_COUNT_HI, Op, MsgBuffer);
749118611Snjl        }
750118611Snjl        break;
751118611Snjl
752118611Snjl
753118611Snjl    default:
754118611Snjl
755118611Snjl        Gbl_ReservedMethods++;
756118611Snjl
757118611Snjl        /* Matched a reserved method name */
758118611Snjl
759118611Snjl        if (MethodInfo->NumArguments != ReservedMethods[Index].NumArguments)
760118611Snjl        {
761167802Sjkim            sprintf (MsgBuffer, "%s requires %d",
762118611Snjl                        ReservedMethods[Index].Name,
763118611Snjl                        ReservedMethods[Index].NumArguments);
764118611Snjl
765118611Snjl            if (MethodInfo->NumArguments > ReservedMethods[Index].NumArguments)
766118611Snjl            {
767151937Sjkim                AslError (ASL_WARNING, ASL_MSG_RESERVED_ARG_COUNT_HI, Op,
768151937Sjkim                    MsgBuffer);
769118611Snjl            }
770118611Snjl            else
771118611Snjl            {
772151937Sjkim                AslError (ASL_WARNING, ASL_MSG_RESERVED_ARG_COUNT_LO, Op,
773151937Sjkim                    MsgBuffer);
774118611Snjl            }
775118611Snjl        }
776118611Snjl
777118611Snjl        if (MethodInfo->NumReturnNoValue &&
778118611Snjl            ReservedMethods[Index].Flags & ASL_RSVD_RETURN_VALUE)
779118611Snjl        {
780118611Snjl            sprintf (MsgBuffer, "%s", ReservedMethods[Index].Name);
781118611Snjl
782118611Snjl            AslError (ASL_WARNING, ASL_MSG_RESERVED_RETURN_VALUE, Op, MsgBuffer);
783118611Snjl        }
784118611Snjl        break;
785118611Snjl    }
786118611Snjl}
787118611Snjl
788118611Snjl
789151937Sjkim/*******************************************************************************
790151937Sjkim *
791151937Sjkim * FUNCTION:    AnMapObjTypeToBtype
792151937Sjkim *
793151937Sjkim * PARAMETERS:  Op              - A parse node
794151937Sjkim *
795151937Sjkim * RETURN:      A Btype
796151937Sjkim *
797151937Sjkim * DESCRIPTION: Map object to the associated "Btype"
798151937Sjkim *
799151937Sjkim ******************************************************************************/
800151937Sjkim
801151937Sjkimstatic UINT32
802138287SmarksAnMapObjTypeToBtype (
803138287Smarks    ACPI_PARSE_OBJECT       *Op)
804138287Smarks{
805138287Smarks
806138287Smarks    switch (Op->Asl.ParseOpcode)
807138287Smarks    {
808138287Smarks    case PARSEOP_OBJECTTYPE_BFF:        /* "BuffFieldObj" */
809138287Smarks        return (ACPI_BTYPE_BUFFER_FIELD);
810138287Smarks
811138287Smarks    case PARSEOP_OBJECTTYPE_BUF:        /* "BuffObj" */
812138287Smarks        return (ACPI_BTYPE_BUFFER);
813138287Smarks
814138287Smarks    case PARSEOP_OBJECTTYPE_DDB:        /* "DDBHandleObj" */
815138287Smarks        return (ACPI_BTYPE_DDB_HANDLE);
816138287Smarks
817138287Smarks    case PARSEOP_OBJECTTYPE_DEV:        /* "DeviceObj" */
818138287Smarks        return (ACPI_BTYPE_DEVICE);
819138287Smarks
820138287Smarks    case PARSEOP_OBJECTTYPE_EVT:        /* "EventObj" */
821138287Smarks        return (ACPI_BTYPE_EVENT);
822138287Smarks
823138287Smarks    case PARSEOP_OBJECTTYPE_FLD:        /* "FieldUnitObj" */
824138287Smarks        return (ACPI_BTYPE_FIELD_UNIT);
825138287Smarks
826138287Smarks    case PARSEOP_OBJECTTYPE_INT:        /* "IntObj" */
827138287Smarks        return (ACPI_BTYPE_INTEGER);
828138287Smarks
829138287Smarks    case PARSEOP_OBJECTTYPE_MTH:        /* "MethodObj" */
830138287Smarks        return (ACPI_BTYPE_METHOD);
831138287Smarks
832138287Smarks    case PARSEOP_OBJECTTYPE_MTX:        /* "MutexObj" */
833138287Smarks        return (ACPI_BTYPE_MUTEX);
834138287Smarks
835138287Smarks    case PARSEOP_OBJECTTYPE_OPR:        /* "OpRegionObj" */
836138287Smarks        return (ACPI_BTYPE_REGION);
837138287Smarks
838138287Smarks    case PARSEOP_OBJECTTYPE_PKG:        /* "PkgObj" */
839138287Smarks        return (ACPI_BTYPE_PACKAGE);
840138287Smarks
841138287Smarks    case PARSEOP_OBJECTTYPE_POW:        /* "PowerResObj" */
842138287Smarks        return (ACPI_BTYPE_POWER);
843138287Smarks
844138287Smarks    case PARSEOP_OBJECTTYPE_STR:        /* "StrObj" */
845138287Smarks        return (ACPI_BTYPE_STRING);
846138287Smarks
847138287Smarks    case PARSEOP_OBJECTTYPE_THZ:        /* "ThermalZoneObj" */
848138287Smarks        return (ACPI_BTYPE_THERMAL);
849138287Smarks
850138287Smarks    case PARSEOP_OBJECTTYPE_UNK:        /* "UnknownObj" */
851138287Smarks        return (ACPI_BTYPE_OBJECTS_AND_REFS);
852138287Smarks
853138287Smarks    default:
854138287Smarks        return (0);
855138287Smarks    }
856138287Smarks}
857138287Smarks
858138287Smarks
859118611Snjl/*******************************************************************************
860118611Snjl *
861118611Snjl * FUNCTION:    AnMethodAnalysisWalkBegin
862118611Snjl *
863118611Snjl * PARAMETERS:  ASL_WALK_CALLBACK
864118611Snjl *
865118611Snjl * RETURN:      Status
866118611Snjl *
867167802Sjkim * DESCRIPTION: Descending callback for the analysis walk. Check methods for:
868118611Snjl *              1) Initialized local variables
869118611Snjl *              2) Valid arguments
870118611Snjl *              3) Return types
871118611Snjl *
872118611Snjl ******************************************************************************/
873118611Snjl
874118611SnjlACPI_STATUS
875118611SnjlAnMethodAnalysisWalkBegin (
876118611Snjl    ACPI_PARSE_OBJECT       *Op,
877118611Snjl    UINT32                  Level,
878118611Snjl    void                    *Context)
879118611Snjl{
880118611Snjl    ASL_ANALYSIS_WALK_INFO  *WalkInfo = (ASL_ANALYSIS_WALK_INFO *) Context;
881118611Snjl    ASL_METHOD_INFO         *MethodInfo = WalkInfo->MethodStack;
882118611Snjl    ACPI_PARSE_OBJECT       *Next;
883118611Snjl    UINT32                  RegisterNumber;
884118611Snjl    UINT32                  i;
885118611Snjl    char                    LocalName[] = "Local0";
886118611Snjl    char                    ArgName[] = "Arg0";
887138287Smarks    ACPI_PARSE_OBJECT       *ArgNode;
888138287Smarks    ACPI_PARSE_OBJECT       *NextType;
889138287Smarks    ACPI_PARSE_OBJECT       *NextParamType;
890151937Sjkim    UINT8                   ActualArgs = 0;
891118611Snjl
892118611Snjl
893118611Snjl    switch (Op->Asl.ParseOpcode)
894118611Snjl    {
895118611Snjl    case PARSEOP_METHOD:
896118611Snjl
897118611Snjl        TotalMethods++;
898118611Snjl
899151937Sjkim        /* Create and init method info */
900151937Sjkim
901118611Snjl        MethodInfo       = UtLocalCalloc (sizeof (ASL_METHOD_INFO));
902118611Snjl        MethodInfo->Next = WalkInfo->MethodStack;
903118611Snjl        MethodInfo->Op = Op;
904118611Snjl
905118611Snjl        WalkInfo->MethodStack = MethodInfo;
906118611Snjl
907138287Smarks        /* Get the name node, ignored here */
908138287Smarks
909138287Smarks        Next = Op->Asl.Child;
910138287Smarks
911118611Snjl        /* Get the NumArguments node */
912118611Snjl
913118611Snjl        Next = Next->Asl.Next;
914151937Sjkim        MethodInfo->NumArguments = (UINT8)
915151937Sjkim            (((UINT8) Next->Asl.Value.Integer) & 0x07);
916118611Snjl
917138287Smarks        /* Get the SerializeRule and SyncLevel nodes, ignored here */
918138287Smarks
919138287Smarks        Next = Next->Asl.Next;
920138287Smarks        Next = Next->Asl.Next;
921138287Smarks        ArgNode = Next;
922138287Smarks
923138287Smarks        /* Get the ReturnType node */
924138287Smarks
925138287Smarks        Next = Next->Asl.Next;
926138287Smarks
927138287Smarks        NextType = Next->Asl.Child;
928138287Smarks        while (NextType)
929138287Smarks        {
930138287Smarks            /* Get and map each of the ReturnTypes */
931138287Smarks
932138287Smarks            MethodInfo->ValidReturnTypes |= AnMapObjTypeToBtype (NextType);
933138287Smarks            NextType->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
934138287Smarks            NextType = NextType->Asl.Next;
935138287Smarks        }
936138287Smarks
937138287Smarks        /* Get the ParameterType node */
938138287Smarks
939138287Smarks        Next = Next->Asl.Next;
940138287Smarks
941138287Smarks        NextType = Next->Asl.Child;
942138287Smarks        while (NextType)
943138287Smarks        {
944138287Smarks            if (NextType->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG)
945138287Smarks            {
946138287Smarks                NextParamType = NextType->Asl.Child;
947138287Smarks                while (NextParamType)
948138287Smarks                {
949138287Smarks                    MethodInfo->ValidArgTypes[ActualArgs] |= AnMapObjTypeToBtype (NextParamType);
950138287Smarks                    NextParamType->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
951138287Smarks                    NextParamType = NextParamType->Asl.Next;
952138287Smarks                }
953138287Smarks            }
954138287Smarks            else
955138287Smarks            {
956151937Sjkim                MethodInfo->ValidArgTypes[ActualArgs] =
957151937Sjkim                    AnMapObjTypeToBtype (NextType);
958138287Smarks                NextType->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG;
959138287Smarks            }
960138287Smarks
961138287Smarks            ActualArgs++;
962138287Smarks            NextType = NextType->Asl.Next;
963138287Smarks        }
964138287Smarks
965138287Smarks        if ((MethodInfo->NumArguments) &&
966138287Smarks            (MethodInfo->NumArguments != ActualArgs))
967138287Smarks        {
968138287Smarks            /* error: Param list did not match number of args */
969138287Smarks        }
970138287Smarks
971138287Smarks        /* Allow numarguments == 0 for Function() */
972138287Smarks
973138287Smarks        if ((!MethodInfo->NumArguments) && (ActualArgs))
974138287Smarks        {
975138287Smarks            MethodInfo->NumArguments = ActualArgs;
976138287Smarks            ArgNode->Asl.Value.Integer |= ActualArgs;
977138287Smarks        }
978138287Smarks
979118611Snjl        /*
980118611Snjl         * Actual arguments are initialized at method entry.
981118611Snjl         * All other ArgX "registers" can be used as locals, so we
982118611Snjl         * track their initialization.
983118611Snjl         */
984118611Snjl        for (i = 0; i < MethodInfo->NumArguments; i++)
985118611Snjl        {
986118611Snjl            MethodInfo->ArgInitialized[i] = TRUE;
987118611Snjl        }
988118611Snjl        break;
989118611Snjl
990118611Snjl
991118611Snjl    case PARSEOP_METHODCALL:
992118611Snjl
993118611Snjl        if (MethodInfo &&
994118611Snjl           (Op->Asl.Node == MethodInfo->Op->Asl.Node))
995118611Snjl        {
996118611Snjl            AslError (ASL_REMARK, ASL_MSG_RECURSION, Op, Op->Asl.ExternalName);
997118611Snjl        }
998118611Snjl        break;
999118611Snjl
1000118611Snjl
1001118611Snjl    case PARSEOP_LOCAL0:
1002118611Snjl    case PARSEOP_LOCAL1:
1003118611Snjl    case PARSEOP_LOCAL2:
1004118611Snjl    case PARSEOP_LOCAL3:
1005118611Snjl    case PARSEOP_LOCAL4:
1006118611Snjl    case PARSEOP_LOCAL5:
1007118611Snjl    case PARSEOP_LOCAL6:
1008118611Snjl    case PARSEOP_LOCAL7:
1009118611Snjl
1010118611Snjl        if (!MethodInfo)
1011118611Snjl        {
1012151937Sjkim            /*
1013151937Sjkim             * Probably was an error in the method declaration,
1014151937Sjkim             * no additional error here
1015151937Sjkim             */
1016167802Sjkim            ACPI_WARNING ((AE_INFO, "%p, No parent method", Op));
1017118611Snjl            return (AE_ERROR);
1018118611Snjl        }
1019118611Snjl
1020118611Snjl        RegisterNumber = (Op->Asl.AmlOpcode & 0x000F);
1021118611Snjl
1022118611Snjl        /*
1023118611Snjl         * If the local is being used as a target, mark the local
1024118611Snjl         * initialized
1025118611Snjl         */
1026118611Snjl        if (Op->Asl.CompileFlags & NODE_IS_TARGET)
1027118611Snjl        {
1028118611Snjl            MethodInfo->LocalInitialized[RegisterNumber] = TRUE;
1029118611Snjl        }
1030118611Snjl
1031118611Snjl        /*
1032118611Snjl         * Otherwise, this is a reference, check if the local
1033118611Snjl         * has been previously initialized.
1034138287Smarks         *
1035138287Smarks         * The only operator that accepts an uninitialized value is ObjectType()
1036118611Snjl         */
1037138287Smarks        else if ((!MethodInfo->LocalInitialized[RegisterNumber]) &&
1038138287Smarks                 (Op->Asl.Parent->Asl.ParseOpcode != PARSEOP_OBJECTTYPE))
1039118611Snjl        {
1040118611Snjl            LocalName[strlen (LocalName) -1] = (char) (RegisterNumber + 0x30);
1041118611Snjl            AslError (ASL_ERROR, ASL_MSG_LOCAL_INIT, Op, LocalName);
1042118611Snjl        }
1043118611Snjl        break;
1044118611Snjl
1045118611Snjl
1046118611Snjl    case PARSEOP_ARG0:
1047118611Snjl    case PARSEOP_ARG1:
1048118611Snjl    case PARSEOP_ARG2:
1049118611Snjl    case PARSEOP_ARG3:
1050118611Snjl    case PARSEOP_ARG4:
1051118611Snjl    case PARSEOP_ARG5:
1052118611Snjl    case PARSEOP_ARG6:
1053118611Snjl
1054118611Snjl        if (!MethodInfo)
1055118611Snjl        {
1056151937Sjkim            /*
1057151937Sjkim             * Probably was an error in the method declaration,
1058151937Sjkim             * no additional error here
1059151937Sjkim             */
1060167802Sjkim            ACPI_WARNING ((AE_INFO, "%p, No parent method", Op));
1061118611Snjl            return (AE_ERROR);
1062118611Snjl        }
1063118611Snjl
1064118611Snjl        RegisterNumber = (Op->Asl.AmlOpcode & 0x000F) - 8;
1065118611Snjl        ArgName[strlen (ArgName) -1] = (char) (RegisterNumber + 0x30);
1066118611Snjl
1067118611Snjl        /*
1068118611Snjl         * If the Arg is being used as a target, mark the local
1069118611Snjl         * initialized
1070118611Snjl         */
1071118611Snjl        if (Op->Asl.CompileFlags & NODE_IS_TARGET)
1072118611Snjl        {
1073118611Snjl            MethodInfo->ArgInitialized[RegisterNumber] = TRUE;
1074118611Snjl        }
1075118611Snjl
1076118611Snjl        /*
1077118611Snjl         * Otherwise, this is a reference, check if the Arg
1078118611Snjl         * has been previously initialized.
1079138287Smarks         *
1080138287Smarks         * The only operator that accepts an uninitialized value is ObjectType()
1081118611Snjl         */
1082138287Smarks        else if ((!MethodInfo->ArgInitialized[RegisterNumber]) &&
1083138287Smarks                 (Op->Asl.Parent->Asl.ParseOpcode != PARSEOP_OBJECTTYPE))
1084118611Snjl        {
1085118611Snjl            AslError (ASL_ERROR, ASL_MSG_ARG_INIT, Op, ArgName);
1086118611Snjl        }
1087118611Snjl
1088118611Snjl        /* Flag this arg if it is not a "real" argument to the method */
1089118611Snjl
1090118611Snjl        if (RegisterNumber >= MethodInfo->NumArguments)
1091118611Snjl        {
1092118611Snjl            AslError (ASL_REMARK, ASL_MSG_NOT_PARAMETER, Op, ArgName);
1093118611Snjl        }
1094118611Snjl        break;
1095118611Snjl
1096118611Snjl
1097118611Snjl    case PARSEOP_RETURN:
1098118611Snjl
1099118611Snjl        if (!MethodInfo)
1100118611Snjl        {
1101151937Sjkim            /*
1102151937Sjkim             * Probably was an error in the method declaration,
1103151937Sjkim             * no additional error here
1104151937Sjkim             */
1105167802Sjkim            ACPI_WARNING ((AE_INFO, "%p, No parent method", Op));
1106118611Snjl            return (AE_ERROR);
1107118611Snjl        }
1108118611Snjl
1109118611Snjl        /* Child indicates a return value */
1110118611Snjl
1111118611Snjl        if ((Op->Asl.Child) &&
1112118611Snjl            (Op->Asl.Child->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG))
1113118611Snjl        {
1114118611Snjl            MethodInfo->NumReturnWithValue++;
1115118611Snjl        }
1116118611Snjl        else
1117118611Snjl        {
1118118611Snjl            MethodInfo->NumReturnNoValue++;
1119118611Snjl        }
1120118611Snjl        break;
1121118611Snjl
1122118611Snjl
1123118611Snjl    case PARSEOP_BREAK:
1124118611Snjl    case PARSEOP_CONTINUE:
1125118611Snjl
1126118611Snjl        Next = Op->Asl.Parent;
1127118611Snjl        while (Next)
1128118611Snjl        {
1129118611Snjl            if (Next->Asl.ParseOpcode == PARSEOP_WHILE)
1130118611Snjl            {
1131118611Snjl                break;
1132118611Snjl            }
1133118611Snjl            Next = Next->Asl.Parent;
1134118611Snjl        }
1135118611Snjl
1136118611Snjl        if (!Next)
1137118611Snjl        {
1138118611Snjl            AslError (ASL_ERROR, ASL_MSG_NO_WHILE, Op, NULL);
1139118611Snjl        }
1140118611Snjl        break;
1141118611Snjl
1142118611Snjl
1143123315Snjl    case PARSEOP_STALL:
1144123315Snjl
1145151937Sjkim        /* We can range check if the argument is an integer */
1146151937Sjkim
1147151937Sjkim        if ((Op->Asl.Child->Asl.ParseOpcode == PARSEOP_INTEGER) &&
1148151937Sjkim            (Op->Asl.Child->Asl.Value.Integer > ACPI_UINT8_MAX))
1149123315Snjl        {
1150123315Snjl            AslError (ASL_ERROR, ASL_MSG_INVALID_TIME, Op, NULL);
1151123315Snjl        }
1152123315Snjl        break;
1153123315Snjl
1154123315Snjl
1155118611Snjl    case PARSEOP_DEVICE:
1156118611Snjl    case PARSEOP_EVENT:
1157118611Snjl    case PARSEOP_MUTEX:
1158118611Snjl    case PARSEOP_OPERATIONREGION:
1159118611Snjl    case PARSEOP_POWERRESOURCE:
1160118611Snjl    case PARSEOP_PROCESSOR:
1161118611Snjl    case PARSEOP_THERMALZONE:
1162118611Snjl
1163118611Snjl        /*
1164118611Snjl         * The first operand is a name to be created in the namespace.
1165118611Snjl         * Check against the reserved list.
1166118611Snjl         */
1167118611Snjl        i = AnCheckForReservedName (Op, Op->Asl.NameSeg);
1168118611Snjl        if (i < ACPI_VALID_RESERVED_NAME_MAX)
1169118611Snjl        {
1170118611Snjl            AslError (ASL_ERROR, ASL_MSG_RESERVED_USE, Op, Op->Asl.ExternalName);
1171118611Snjl        }
1172118611Snjl        break;
1173118611Snjl
1174118611Snjl
1175118611Snjl    case PARSEOP_NAME:
1176118611Snjl
1177118611Snjl        i = AnCheckForReservedName (Op, Op->Asl.NameSeg);
1178118611Snjl        if (i < ACPI_VALID_RESERVED_NAME_MAX)
1179118611Snjl        {
1180118611Snjl            if (ReservedMethods[i].NumArguments > 0)
1181118611Snjl            {
1182118611Snjl                /*
1183118611Snjl                 * This reserved name must be a control method because
1184118611Snjl                 * it must have arguments
1185118611Snjl                 */
1186151937Sjkim                AslError (ASL_ERROR, ASL_MSG_RESERVED_METHOD, Op,
1187151937Sjkim                    "with arguments");
1188118611Snjl            }
1189118611Snjl
1190151937Sjkim            /* Typechecking for _HID */
1191151937Sjkim
1192118611Snjl            else if (!ACPI_STRCMP (METHOD_NAME__HID, ReservedMethods[i].Name))
1193118611Snjl            {
1194118611Snjl                /* Examine the second operand to typecheck it */
1195118611Snjl
1196118611Snjl                Next = Op->Asl.Child->Asl.Next;
1197118611Snjl
1198118611Snjl                if ((Next->Asl.ParseOpcode != PARSEOP_INTEGER) &&
1199118611Snjl                    (Next->Asl.ParseOpcode != PARSEOP_STRING_LITERAL))
1200118611Snjl                {
1201118611Snjl                    /* _HID must be a string or an integer */
1202118611Snjl
1203151937Sjkim                    AslError (ASL_ERROR, ASL_MSG_RESERVED_OPERAND_TYPE, Next,
1204151937Sjkim                        "String or Integer");
1205118611Snjl                }
1206118611Snjl
1207118611Snjl                if (Next->Asl.ParseOpcode == PARSEOP_STRING_LITERAL)
1208118611Snjl                {
1209118611Snjl                    /*
1210118611Snjl                     * _HID is a string, all characters must be alphanumeric.
1211118611Snjl                     * One of the things we want to catch here is the use of
1212118611Snjl                     * a leading asterisk in the string.
1213118611Snjl                     */
1214118611Snjl                    for (i = 0; Next->Asl.Value.String[i]; i++)
1215118611Snjl                    {
1216118611Snjl                        if (!isalnum (Next->Asl.Value.String[i]))
1217118611Snjl                        {
1218151937Sjkim                            AslError (ASL_ERROR, ASL_MSG_ALPHANUMERIC_STRING,
1219151937Sjkim                                Next, Next->Asl.Value.String);
1220118611Snjl                            break;
1221118611Snjl                        }
1222118611Snjl                    }
1223118611Snjl                }
1224118611Snjl            }
1225118611Snjl        }
1226118611Snjl        break;
1227118611Snjl
1228118611Snjl
1229118611Snjl    default:
1230118611Snjl        break;
1231118611Snjl    }
1232118611Snjl
1233118611Snjl    return AE_OK;
1234118611Snjl}
1235118611Snjl
1236118611Snjl
1237118611Snjl/*******************************************************************************
1238118611Snjl *
1239118611Snjl * FUNCTION:    AnLastStatementIsReturn
1240118611Snjl *
1241118611Snjl * PARAMETERS:  Op            - A method parse node
1242118611Snjl *
1243167802Sjkim * RETURN:      TRUE if last statement is an ASL RETURN. False otherwise
1244118611Snjl *
1245118611Snjl * DESCRIPTION: Walk down the list of top level statements within a method
1246167802Sjkim *              to find the last one. Check if that last statement is in
1247118611Snjl *              fact a RETURN statement.
1248118611Snjl *
1249118611Snjl ******************************************************************************/
1250118611Snjl
1251151937Sjkimstatic BOOLEAN
1252118611SnjlAnLastStatementIsReturn (
1253118611Snjl    ACPI_PARSE_OBJECT       *Op)
1254118611Snjl{
1255118611Snjl    ACPI_PARSE_OBJECT       *Next;
1256118611Snjl
1257118611Snjl
1258118611Snjl    /*
1259118611Snjl     * Check if last statement is a return
1260118611Snjl     */
1261118611Snjl    Next = ASL_GET_CHILD_NODE (Op);
1262118611Snjl    while (Next)
1263118611Snjl    {
1264118611Snjl        if ((!Next->Asl.Next) &&
1265118611Snjl            (Next->Asl.ParseOpcode == PARSEOP_RETURN))
1266118611Snjl        {
1267118611Snjl            return TRUE;
1268118611Snjl        }
1269118611Snjl
1270118611Snjl        Next = ASL_GET_PEER_NODE (Next);
1271118611Snjl    }
1272118611Snjl
1273118611Snjl    return FALSE;
1274118611Snjl}
1275118611Snjl
1276118611Snjl
1277118611Snjl/*******************************************************************************
1278118611Snjl *
1279118611Snjl * FUNCTION:    AnMethodAnalysisWalkEnd
1280118611Snjl *
1281118611Snjl * PARAMETERS:  ASL_WALK_CALLBACK
1282118611Snjl *
1283118611Snjl * RETURN:      Status
1284118611Snjl *
1285167802Sjkim * DESCRIPTION: Ascending callback for analysis walk. Complete method
1286118611Snjl *              return analysis.
1287118611Snjl *
1288118611Snjl ******************************************************************************/
1289118611Snjl
1290118611SnjlACPI_STATUS
1291118611SnjlAnMethodAnalysisWalkEnd (
1292118611Snjl    ACPI_PARSE_OBJECT       *Op,
1293118611Snjl    UINT32                  Level,
1294118611Snjl    void                    *Context)
1295118611Snjl{
1296118611Snjl    ASL_ANALYSIS_WALK_INFO  *WalkInfo = (ASL_ANALYSIS_WALK_INFO *) Context;
1297118611Snjl    ASL_METHOD_INFO         *MethodInfo = WalkInfo->MethodStack;
1298118611Snjl
1299118611Snjl
1300118611Snjl    switch (Op->Asl.ParseOpcode)
1301118611Snjl    {
1302118611Snjl    case PARSEOP_METHOD:
1303118611Snjl    case PARSEOP_RETURN:
1304118611Snjl        if (!MethodInfo)
1305118611Snjl        {
1306118611Snjl            printf ("No method info for method! [%s]\n", Op->Asl.Namepath);
1307151937Sjkim            AslError (ASL_ERROR, ASL_MSG_COMPILER_INTERNAL, Op,
1308151937Sjkim                "No method info for this method");
1309118611Snjl            CmCleanupAndExit ();
1310118611Snjl            return (AE_AML_INTERNAL);
1311118611Snjl        }
1312118611Snjl        break;
1313118611Snjl
1314118611Snjl    default:
1315118611Snjl        break;
1316118611Snjl    }
1317118611Snjl
1318118611Snjl    switch (Op->Asl.ParseOpcode)
1319118611Snjl    {
1320118611Snjl    case PARSEOP_METHOD:
1321118611Snjl
1322118611Snjl        WalkInfo->MethodStack = MethodInfo->Next;
1323118611Snjl
1324118611Snjl        /*
1325118611Snjl         * Check if there is no return statement at the end of the
1326118611Snjl         * method AND we can actually get there -- i.e., the execution
1327118611Snjl         * of the method can possibly terminate without a return statement.
1328118611Snjl         */
1329118611Snjl        if ((!AnLastStatementIsReturn (Op)) &&
1330118611Snjl            (!(Op->Asl.CompileFlags & NODE_HAS_NO_EXIT)))
1331118611Snjl        {
1332118611Snjl            /*
1333118611Snjl             * No return statement, and execution can possibly exit
1334167802Sjkim             * via this path. This is equivalent to Return ()
1335118611Snjl             */
1336118611Snjl            MethodInfo->NumReturnNoValue++;
1337118611Snjl        }
1338118611Snjl
1339118611Snjl        /*
1340118611Snjl         * Check for case where some return statements have a return value
1341167802Sjkim         * and some do not. Exit without a return statement is a return with
1342118611Snjl         * no value
1343118611Snjl         */
1344118611Snjl        if (MethodInfo->NumReturnNoValue &&
1345118611Snjl            MethodInfo->NumReturnWithValue)
1346118611Snjl        {
1347151937Sjkim            AslError (ASL_WARNING, ASL_MSG_RETURN_TYPES, Op,
1348151937Sjkim                Op->Asl.ExternalName);
1349118611Snjl        }
1350118611Snjl
1351118611Snjl        /*
1352118611Snjl         * If there are any RETURN() statements with no value, or there is a
1353118611Snjl         * control path that allows the method to exit without a return value,
1354167802Sjkim         * we mark the method as a method that does not return a value. This
1355118611Snjl         * knowledge can be used to check method invocations that expect a
1356118611Snjl         * returned value.
1357118611Snjl         */
1358118611Snjl        if (MethodInfo->NumReturnNoValue)
1359118611Snjl        {
1360118611Snjl            if (MethodInfo->NumReturnWithValue)
1361118611Snjl            {
1362118611Snjl                Op->Asl.CompileFlags |= NODE_METHOD_SOME_NO_RETVAL;
1363118611Snjl            }
1364118611Snjl            else
1365118611Snjl            {
1366118611Snjl                Op->Asl.CompileFlags |= NODE_METHOD_NO_RETVAL;
1367118611Snjl            }
1368118611Snjl        }
1369118611Snjl
1370118611Snjl        /*
1371118611Snjl         * Check predefined method names for correct return behavior
1372118611Snjl         * and correct number of arguments
1373118611Snjl         */
1374118611Snjl        AnCheckForReservedMethod (Op, MethodInfo);
1375167802Sjkim        ACPI_FREE (MethodInfo);
1376118611Snjl        break;
1377118611Snjl
1378118611Snjl
1379118611Snjl    case PARSEOP_RETURN:
1380118611Snjl
1381118611Snjl        /*
1382118611Snjl         * The parent block does not "exit" and continue execution -- the
1383118611Snjl         * method is terminated here with the Return() statement.
1384118611Snjl         */
1385118611Snjl        Op->Asl.Parent->Asl.CompileFlags |= NODE_HAS_NO_EXIT;
1386118611Snjl
1387151937Sjkim        /* Used in the "typing" pass later */
1388151937Sjkim
1389151937Sjkim        Op->Asl.ParentMethod = MethodInfo->Op;
1390151937Sjkim
1391118611Snjl        /*
1392118611Snjl         * If there is a peer node after the return statement, then this
1393151937Sjkim         * node is unreachable code -- i.e., it won't be executed because of
1394167802Sjkim         * the preceeding Return() statement.
1395118611Snjl         */
1396118611Snjl        if (Op->Asl.Next)
1397118611Snjl        {
1398118611Snjl            AslError (ASL_WARNING, ASL_MSG_UNREACHABLE_CODE, Op->Asl.Next, NULL);
1399118611Snjl        }
1400118611Snjl        break;
1401118611Snjl
1402118611Snjl
1403118611Snjl    case PARSEOP_IF:
1404118611Snjl
1405118611Snjl        if ((Op->Asl.CompileFlags & NODE_HAS_NO_EXIT) &&
1406118611Snjl            (Op->Asl.Next) &&
1407118611Snjl            (Op->Asl.Next->Asl.ParseOpcode == PARSEOP_ELSE))
1408118611Snjl        {
1409118611Snjl            /*
1410167802Sjkim             * This IF has a corresponding ELSE. The IF block has no exit,
1411118611Snjl             * (it contains an unconditional Return)
1412118611Snjl             * mark the ELSE block to remember this fact.
1413118611Snjl             */
1414118611Snjl            Op->Asl.Next->Asl.CompileFlags |= NODE_IF_HAS_NO_EXIT;
1415118611Snjl        }
1416118611Snjl        break;
1417118611Snjl
1418118611Snjl
1419118611Snjl    case PARSEOP_ELSE:
1420118611Snjl
1421118611Snjl        if ((Op->Asl.CompileFlags & NODE_HAS_NO_EXIT) &&
1422118611Snjl            (Op->Asl.CompileFlags & NODE_IF_HAS_NO_EXIT))
1423118611Snjl        {
1424118611Snjl            /*
1425118611Snjl             * This ELSE block has no exit and the corresponding IF block
1426167802Sjkim             * has no exit either. Therefore, the parent node has no exit.
1427118611Snjl             */
1428118611Snjl            Op->Asl.Parent->Asl.CompileFlags |= NODE_HAS_NO_EXIT;
1429118611Snjl        }
1430118611Snjl        break;
1431118611Snjl
1432118611Snjl
1433118611Snjl    default:
1434118611Snjl
1435118611Snjl        if ((Op->Asl.CompileFlags & NODE_HAS_NO_EXIT) &&
1436118611Snjl            (Op->Asl.Parent))
1437118611Snjl        {
1438118611Snjl            /* If this node has no exit, then the parent has no exit either */
1439118611Snjl
1440118611Snjl            Op->Asl.Parent->Asl.CompileFlags |= NODE_HAS_NO_EXIT;
1441118611Snjl        }
1442118611Snjl        break;
1443118611Snjl    }
1444118611Snjl
1445118611Snjl    return AE_OK;
1446118611Snjl}
1447118611Snjl
1448118611Snjl
1449118611Snjl/*******************************************************************************
1450118611Snjl *
1451118611Snjl * FUNCTION:    AnMethodTypingWalkBegin
1452118611Snjl *
1453118611Snjl * PARAMETERS:  ASL_WALK_CALLBACK
1454118611Snjl *
1455118611Snjl * RETURN:      Status
1456118611Snjl *
1457118611Snjl * DESCRIPTION: Descending callback for the typing walk.
1458118611Snjl *
1459118611Snjl ******************************************************************************/
1460118611Snjl
1461118611SnjlACPI_STATUS
1462118611SnjlAnMethodTypingWalkBegin (
1463118611Snjl    ACPI_PARSE_OBJECT       *Op,
1464118611Snjl    UINT32                  Level,
1465118611Snjl    void                    *Context)
1466118611Snjl{
1467118611Snjl
1468118611Snjl    return AE_OK;
1469118611Snjl}
1470118611Snjl
1471118611Snjl
1472118611Snjl/*******************************************************************************
1473118611Snjl *
1474118611Snjl * FUNCTION:    AnMethodTypingWalkEnd
1475118611Snjl *
1476118611Snjl * PARAMETERS:  ASL_WALK_CALLBACK
1477118611Snjl *
1478118611Snjl * RETURN:      Status
1479118611Snjl *
1480167802Sjkim * DESCRIPTION: Ascending callback for typing walk. Complete the method
1481167802Sjkim *              return analysis. Check methods for:
1482118611Snjl *              1) Initialized local variables
1483118611Snjl *              2) Valid arguments
1484118611Snjl *              3) Return types
1485118611Snjl *
1486118611Snjl ******************************************************************************/
1487118611Snjl
1488118611SnjlACPI_STATUS
1489118611SnjlAnMethodTypingWalkEnd (
1490118611Snjl    ACPI_PARSE_OBJECT       *Op,
1491118611Snjl    UINT32                  Level,
1492118611Snjl    void                    *Context)
1493118611Snjl{
1494118611Snjl    UINT32                  ThisNodeBtype;
1495118611Snjl
1496118611Snjl
1497118611Snjl    switch (Op->Asl.ParseOpcode)
1498118611Snjl    {
1499118611Snjl    case PARSEOP_METHOD:
1500118611Snjl
1501118611Snjl        Op->Asl.CompileFlags |= NODE_METHOD_TYPED;
1502118611Snjl        break;
1503118611Snjl
1504118611Snjl    case PARSEOP_RETURN:
1505118611Snjl
1506118611Snjl        if ((Op->Asl.Child) &&
1507118611Snjl            (Op->Asl.Child->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG))
1508118611Snjl        {
1509118611Snjl            ThisNodeBtype = AnGetBtype (Op->Asl.Child);
1510118611Snjl
1511118611Snjl            if ((Op->Asl.Child->Asl.ParseOpcode == PARSEOP_METHODCALL) &&
1512118611Snjl                (ThisNodeBtype == (ACPI_UINT32_MAX -1)))
1513118611Snjl            {
1514118611Snjl                /*
1515167802Sjkim                 * The called method is untyped at this time (typically a
1516167802Sjkim                 * forward reference).
1517167802Sjkim                 *
1518167802Sjkim                 * Check for a recursive method call first.
1519118611Snjl                 */
1520167802Sjkim                if (Op->Asl.ParentMethod != Op->Asl.Child->Asl.Node->Op)
1521167802Sjkim                {
1522167802Sjkim                    /* We must type the method here */
1523118611Snjl
1524167802Sjkim                    TrWalkParseTree (Op->Asl.Child->Asl.Node->Op,
1525167802Sjkim                        ASL_WALK_VISIT_TWICE, AnMethodTypingWalkBegin,
1526167802Sjkim                        AnMethodTypingWalkEnd, NULL);
1527167802Sjkim
1528167802Sjkim                    ThisNodeBtype = AnGetBtype (Op->Asl.Child);
1529167802Sjkim                }
1530118611Snjl            }
1531118611Snjl
1532167802Sjkim            /* Returns a value, save the value type */
1533118611Snjl
1534118611Snjl            if (Op->Asl.ParentMethod)
1535118611Snjl            {
1536118611Snjl                Op->Asl.ParentMethod->Asl.AcpiBtype |= ThisNodeBtype;
1537118611Snjl            }
1538118611Snjl        }
1539118611Snjl        break;
1540118611Snjl
1541118611Snjl    default:
1542118611Snjl        break;
1543118611Snjl    }
1544118611Snjl
1545118611Snjl    return AE_OK;
1546118611Snjl}
1547118611Snjl
1548118611Snjl
1549118611Snjl/*******************************************************************************
1550118611Snjl *
1551118611Snjl * FUNCTION:    AnCheckMethodReturnValue
1552118611Snjl *
1553118611Snjl * PARAMETERS:  Op                  - Parent
1554118611Snjl *              OpInfo              - Parent info
1555118611Snjl *              ArgOp               - Method invocation op
1556118611Snjl *              RequiredBtypes      - What caller requires
1557118611Snjl *              ThisNodeBtype       - What this node returns (if anything)
1558118611Snjl *
1559118611Snjl * RETURN:      None
1560118611Snjl *
1561118611Snjl * DESCRIPTION: Check a method invocation for 1) A return value and if it does
1562118611Snjl *              in fact return a value, 2) check the type of the return value.
1563118611Snjl *
1564118611Snjl ******************************************************************************/
1565118611Snjl
1566151937Sjkimstatic void
1567118611SnjlAnCheckMethodReturnValue (
1568118611Snjl    ACPI_PARSE_OBJECT       *Op,
1569118611Snjl    const ACPI_OPCODE_INFO  *OpInfo,
1570118611Snjl    ACPI_PARSE_OBJECT       *ArgOp,
1571118611Snjl    UINT32                  RequiredBtypes,
1572118611Snjl    UINT32                  ThisNodeBtype)
1573118611Snjl{
1574118611Snjl    ACPI_PARSE_OBJECT       *OwningOp;
1575118611Snjl    ACPI_NAMESPACE_NODE     *Node;
1576118611Snjl
1577118611Snjl
1578118611Snjl    Node = ArgOp->Asl.Node;
1579118611Snjl
1580118611Snjl
1581118611Snjl    /* Examine the parent op of this method */
1582118611Snjl
1583151937Sjkim    OwningOp = Node->Op;
1584118611Snjl    if (OwningOp->Asl.CompileFlags & NODE_METHOD_NO_RETVAL)
1585118611Snjl    {
1586151937Sjkim        /* Method NEVER returns a value */
1587151937Sjkim
1588118611Snjl        AslError (ASL_ERROR, ASL_MSG_NO_RETVAL, Op, Op->Asl.ExternalName);
1589118611Snjl    }
1590118611Snjl    else if (OwningOp->Asl.CompileFlags & NODE_METHOD_SOME_NO_RETVAL)
1591118611Snjl    {
1592151937Sjkim        /* Method SOMETIMES returns a value, SOMETIMES not */
1593151937Sjkim
1594118611Snjl        AslError (ASL_WARNING, ASL_MSG_SOME_NO_RETVAL, Op, Op->Asl.ExternalName);
1595118611Snjl    }
1596118611Snjl    else if (!(ThisNodeBtype & RequiredBtypes))
1597118611Snjl    {
1598151937Sjkim        /* Method returns a value, but the type is wrong */
1599151937Sjkim
1600118611Snjl        AnFormatBtype (StringBuffer, ThisNodeBtype);
1601118611Snjl        AnFormatBtype (StringBuffer2, RequiredBtypes);
1602118611Snjl
1603118611Snjl
1604118611Snjl        /*
1605118611Snjl         * The case where the method does not return any value at all
1606118611Snjl         * was already handled in the namespace cross reference
1607118611Snjl         * -- Only issue an error if the method in fact returns a value,
1608118611Snjl         * but it is of the wrong type
1609118611Snjl         */
1610118611Snjl        if (ThisNodeBtype != 0)
1611118611Snjl        {
1612151937Sjkim            sprintf (MsgBuffer,
1613151937Sjkim                "Method returns [%s], %s operator requires [%s]",
1614151937Sjkim                StringBuffer, OpInfo->Name, StringBuffer2);
1615118611Snjl
1616118611Snjl            AslError (ASL_ERROR, ASL_MSG_INVALID_TYPE, ArgOp, MsgBuffer);
1617118611Snjl        }
1618118611Snjl    }
1619118611Snjl}
1620118611Snjl
1621118611Snjl
1622118611Snjl/*******************************************************************************
1623118611Snjl *
1624118611Snjl * FUNCTION:    AnOperandTypecheckWalkBegin
1625118611Snjl *
1626118611Snjl * PARAMETERS:  ASL_WALK_CALLBACK
1627118611Snjl *
1628118611Snjl * RETURN:      Status
1629118611Snjl *
1630167802Sjkim * DESCRIPTION: Descending callback for the analysis walk. Check methods for:
1631118611Snjl *              1) Initialized local variables
1632118611Snjl *              2) Valid arguments
1633118611Snjl *              3) Return types
1634118611Snjl *
1635118611Snjl ******************************************************************************/
1636118611Snjl
1637118611SnjlACPI_STATUS
1638118611SnjlAnOperandTypecheckWalkBegin (
1639118611Snjl    ACPI_PARSE_OBJECT       *Op,
1640118611Snjl    UINT32                  Level,
1641118611Snjl    void                    *Context)
1642118611Snjl{
1643118611Snjl
1644118611Snjl    return AE_OK;
1645118611Snjl}
1646118611Snjl
1647118611Snjl
1648118611Snjl/*******************************************************************************
1649118611Snjl *
1650118611Snjl * FUNCTION:    AnOperandTypecheckWalkEnd
1651118611Snjl *
1652118611Snjl * PARAMETERS:  ASL_WALK_CALLBACK
1653118611Snjl *
1654118611Snjl * RETURN:      Status
1655118611Snjl *
1656167802Sjkim * DESCRIPTION: Ascending callback for analysis walk. Complete method
1657118611Snjl *              return analysis.
1658118611Snjl *
1659118611Snjl ******************************************************************************/
1660118611Snjl
1661118611SnjlACPI_STATUS
1662118611SnjlAnOperandTypecheckWalkEnd (
1663118611Snjl    ACPI_PARSE_OBJECT       *Op,
1664118611Snjl    UINT32                  Level,
1665118611Snjl    void                    *Context)
1666118611Snjl{
1667118611Snjl    const ACPI_OPCODE_INFO  *OpInfo;
1668118611Snjl    UINT32                  RuntimeArgTypes;
1669118611Snjl    UINT32                  RuntimeArgTypes2;
1670118611Snjl    UINT32                  RequiredBtypes;
1671118611Snjl    UINT32                  ThisNodeBtype;
1672118611Snjl    UINT32                  CommonBtypes;
1673118611Snjl    UINT32                  OpcodeClass;
1674118611Snjl    ACPI_PARSE_OBJECT       *ArgOp;
1675118611Snjl    UINT32                  ArgType;
1676118611Snjl
1677118611Snjl
1678118611Snjl    switch (Op->Asl.AmlOpcode)
1679118611Snjl    {
1680118611Snjl    case AML_RAW_DATA_BYTE:
1681118611Snjl    case AML_RAW_DATA_WORD:
1682118611Snjl    case AML_RAW_DATA_DWORD:
1683118611Snjl    case AML_RAW_DATA_QWORD:
1684118611Snjl    case AML_RAW_DATA_BUFFER:
1685118611Snjl    case AML_RAW_DATA_CHAIN:
1686118611Snjl    case AML_PACKAGE_LENGTH:
1687118611Snjl    case AML_UNASSIGNED_OPCODE:
1688118611Snjl    case AML_DEFAULT_ARG_OP:
1689118611Snjl
1690118611Snjl        /* Ignore the internal (compiler-only) AML opcodes */
1691118611Snjl
1692118611Snjl        return (AE_OK);
1693118611Snjl
1694118611Snjl    default:
1695118611Snjl        break;
1696118611Snjl    }
1697118611Snjl
1698118611Snjl    OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode);
1699118611Snjl    if (!OpInfo)
1700118611Snjl    {
1701118611Snjl        return (AE_OK);
1702118611Snjl    }
1703118611Snjl
1704118611Snjl    ArgOp           = Op->Asl.Child;
1705118611Snjl    RuntimeArgTypes = OpInfo->RuntimeArgs;
1706118611Snjl    OpcodeClass     = OpInfo->Class;
1707118611Snjl
1708118611Snjl
1709118611Snjl    /*
1710118611Snjl     * Special case for control opcodes IF/RETURN/WHILE since they
1711118611Snjl     * have no runtime arg list (at this time)
1712118611Snjl     */
1713118611Snjl    switch (Op->Asl.AmlOpcode)
1714118611Snjl    {
1715118611Snjl    case AML_IF_OP:
1716118611Snjl    case AML_WHILE_OP:
1717118611Snjl    case AML_RETURN_OP:
1718118611Snjl
1719118611Snjl        if (ArgOp->Asl.ParseOpcode == PARSEOP_METHODCALL)
1720118611Snjl        {
1721167802Sjkim            /* Check for an internal method */
1722167802Sjkim
1723167802Sjkim            if (AnIsInternalMethod (ArgOp))
1724151937Sjkim            {
1725151937Sjkim                return (AE_OK);
1726151937Sjkim            }
1727151937Sjkim
1728118611Snjl            /* The lone arg is a method call, check it */
1729118611Snjl
1730118611Snjl            RequiredBtypes = AnMapArgTypeToBtype (ARGI_INTEGER);
1731118611Snjl            if (Op->Asl.AmlOpcode == AML_RETURN_OP)
1732118611Snjl            {
1733118611Snjl                RequiredBtypes = 0xFFFFFFFF;
1734118611Snjl            }
1735118611Snjl
1736118611Snjl            ThisNodeBtype = AnGetBtype (ArgOp);
1737118611Snjl            if (ThisNodeBtype == ACPI_UINT32_MAX)
1738118611Snjl            {
1739118611Snjl                return (AE_OK);
1740118611Snjl            }
1741151937Sjkim            AnCheckMethodReturnValue (Op, OpInfo, ArgOp,
1742151937Sjkim                RequiredBtypes, ThisNodeBtype);
1743118611Snjl        }
1744118611Snjl        return (AE_OK);
1745118611Snjl
1746118611Snjl    default:
1747118611Snjl        break;
1748118611Snjl    }
1749118611Snjl
1750118611Snjl    /* Ignore the non-executable opcodes */
1751118611Snjl
1752118611Snjl    if (RuntimeArgTypes == ARGI_INVALID_OPCODE)
1753118611Snjl    {
1754118611Snjl        return (AE_OK);
1755118611Snjl    }
1756118611Snjl
1757118611Snjl    switch (OpcodeClass)
1758118611Snjl    {
1759118611Snjl    case AML_CLASS_EXECUTE:
1760118611Snjl    case AML_CLASS_CREATE:
1761118611Snjl    case AML_CLASS_CONTROL:
1762118611Snjl    case AML_CLASS_RETURN_VALUE:
1763118611Snjl
1764118611Snjl        /* TBD: Change class or fix typechecking for these */
1765118611Snjl
1766118611Snjl        if ((Op->Asl.AmlOpcode == AML_BUFFER_OP)        ||
1767118611Snjl            (Op->Asl.AmlOpcode == AML_PACKAGE_OP)       ||
1768118611Snjl            (Op->Asl.AmlOpcode == AML_VAR_PACKAGE_OP))
1769118611Snjl        {
1770118611Snjl            break;
1771118611Snjl        }
1772118611Snjl
1773118611Snjl        /* Reverse the runtime argument list */
1774118611Snjl
1775118611Snjl        RuntimeArgTypes2 = 0;
1776118611Snjl        while ((ArgType = GET_CURRENT_ARG_TYPE (RuntimeArgTypes)))
1777118611Snjl        {
1778118611Snjl            RuntimeArgTypes2 <<= ARG_TYPE_WIDTH;
1779118611Snjl            RuntimeArgTypes2 |= ArgType;
1780118611Snjl            INCREMENT_ARG_LIST (RuntimeArgTypes);
1781118611Snjl        }
1782118611Snjl
1783118611Snjl        while ((ArgType = GET_CURRENT_ARG_TYPE (RuntimeArgTypes2)))
1784118611Snjl        {
1785118611Snjl            RequiredBtypes = AnMapArgTypeToBtype (ArgType);
1786118611Snjl
1787118611Snjl            ThisNodeBtype = AnGetBtype (ArgOp);
1788118611Snjl            if (ThisNodeBtype == ACPI_UINT32_MAX)
1789118611Snjl            {
1790118611Snjl                goto NextArgument;
1791118611Snjl            }
1792118611Snjl
1793118611Snjl            /* Examine the arg based on the required type of the arg */
1794118611Snjl
1795118611Snjl            switch (ArgType)
1796118611Snjl            {
1797118611Snjl            case ARGI_TARGETREF:
1798118611Snjl
1799118611Snjl                if (ArgOp->Asl.ParseOpcode == PARSEOP_ZERO)
1800118611Snjl                {
1801118611Snjl                    /* ZERO is the placeholder for "don't store result" */
1802118611Snjl
1803118611Snjl                    ThisNodeBtype = RequiredBtypes;
1804118611Snjl                    break;
1805118611Snjl                }
1806118611Snjl
1807118611Snjl                if (ArgOp->Asl.ParseOpcode == PARSEOP_INTEGER)
1808118611Snjl                {
1809118611Snjl                    /*
1810118611Snjl                     * This is the case where an original reference to a resource
1811118611Snjl                     * descriptor field has been replaced by an (Integer) offset.
1812118611Snjl                     * These named fields are supported at compile-time only;
1813118611Snjl                     * the names are not passed to the interpreter (via the AML).
1814118611Snjl                     */
1815118611Snjl                    if ((ArgOp->Asl.Node->Type == ACPI_TYPE_LOCAL_RESOURCE_FIELD) ||
1816118611Snjl                        (ArgOp->Asl.Node->Type == ACPI_TYPE_LOCAL_RESOURCE))
1817118611Snjl                    {
1818118611Snjl                        AslError (ASL_ERROR, ASL_MSG_RESOURCE_FIELD, ArgOp, NULL);
1819118611Snjl                    }
1820118611Snjl                    else
1821118611Snjl                    {
1822118611Snjl                        AslError (ASL_ERROR, ASL_MSG_INVALID_TYPE, ArgOp, NULL);
1823118611Snjl                    }
1824118611Snjl                    break;
1825118611Snjl                }
1826118611Snjl
1827118611Snjl                if ((ArgOp->Asl.ParseOpcode == PARSEOP_METHODCALL) ||
1828118611Snjl                    (ArgOp->Asl.ParseOpcode == PARSEOP_DEREFOF))
1829118611Snjl                {
1830118611Snjl                    break;
1831118611Snjl                }
1832118611Snjl
1833118611Snjl                ThisNodeBtype = RequiredBtypes;
1834118611Snjl                break;
1835118611Snjl
1836118611Snjl
1837118611Snjl            case ARGI_REFERENCE:            /* References */
1838118611Snjl            case ARGI_INTEGER_REF:
1839118611Snjl            case ARGI_OBJECT_REF:
1840118611Snjl            case ARGI_DEVICE_REF:
1841118611Snjl
1842118611Snjl                switch (ArgOp->Asl.ParseOpcode)
1843118611Snjl                {
1844118611Snjl                case PARSEOP_LOCAL0:
1845118611Snjl                case PARSEOP_LOCAL1:
1846118611Snjl                case PARSEOP_LOCAL2:
1847118611Snjl                case PARSEOP_LOCAL3:
1848118611Snjl                case PARSEOP_LOCAL4:
1849118611Snjl                case PARSEOP_LOCAL5:
1850118611Snjl                case PARSEOP_LOCAL6:
1851118611Snjl                case PARSEOP_LOCAL7:
1852118611Snjl
1853118611Snjl                    /* TBD: implement analysis of current value (type) of the local */
1854118611Snjl                    /* For now, just treat any local as a typematch */
1855118611Snjl
1856118611Snjl                    /*ThisNodeBtype = RequiredBtypes;*/
1857118611Snjl                    break;
1858118611Snjl
1859118611Snjl                case PARSEOP_ARG0:
1860118611Snjl                case PARSEOP_ARG1:
1861118611Snjl                case PARSEOP_ARG2:
1862118611Snjl                case PARSEOP_ARG3:
1863118611Snjl                case PARSEOP_ARG4:
1864118611Snjl                case PARSEOP_ARG5:
1865118611Snjl                case PARSEOP_ARG6:
1866118611Snjl
1867118611Snjl                    /* Hard to analyze argument types, sow we won't */
1868118611Snjl                    /* For now, just treat any arg as a typematch */
1869118611Snjl
1870118611Snjl                    /* ThisNodeBtype = RequiredBtypes; */
1871118611Snjl                    break;
1872118611Snjl
1873118611Snjl                case PARSEOP_DEBUG:
1874118611Snjl                    break;
1875118611Snjl
1876118611Snjl                case PARSEOP_REFOF:
1877118611Snjl                case PARSEOP_INDEX:
1878118611Snjl                default:
1879118611Snjl                    break;
1880118611Snjl
1881118611Snjl                }
1882118611Snjl                break;
1883118611Snjl
1884118611Snjl            case ARGI_INTEGER:
1885118611Snjl            default:
1886118611Snjl                break;
1887118611Snjl            }
1888118611Snjl
1889118611Snjl
1890118611Snjl            CommonBtypes = ThisNodeBtype & RequiredBtypes;
1891118611Snjl
1892118611Snjl            if (ArgOp->Asl.ParseOpcode == PARSEOP_METHODCALL)
1893118611Snjl            {
1894167802Sjkim                if (AnIsInternalMethod (ArgOp))
1895167802Sjkim                {
1896167802Sjkim                    return (AE_OK);
1897167802Sjkim                }
1898167802Sjkim
1899118611Snjl                /* Check a method call for a valid return value */
1900118611Snjl
1901151937Sjkim                AnCheckMethodReturnValue (Op, OpInfo, ArgOp,
1902151937Sjkim                    RequiredBtypes, ThisNodeBtype);
1903118611Snjl            }
1904118611Snjl
1905118611Snjl            /*
1906118611Snjl             * Now check if the actual type(s) match at least one
1907118611Snjl             * bit to the required type
1908118611Snjl             */
1909118611Snjl            else if (!CommonBtypes)
1910118611Snjl            {
1911118611Snjl                /* No match -- this is a type mismatch error */
1912118611Snjl
1913118611Snjl                AnFormatBtype (StringBuffer, ThisNodeBtype);
1914118611Snjl                AnFormatBtype (StringBuffer2, RequiredBtypes);
1915118611Snjl
1916118611Snjl                sprintf (MsgBuffer, "[%s] found, %s operator requires [%s]",
1917118611Snjl                            StringBuffer, OpInfo->Name, StringBuffer2);
1918118611Snjl
1919118611Snjl                AslError (ASL_ERROR, ASL_MSG_INVALID_TYPE, ArgOp, MsgBuffer);
1920118611Snjl            }
1921118611Snjl
1922118611Snjl        NextArgument:
1923118611Snjl            ArgOp = ArgOp->Asl.Next;
1924118611Snjl            INCREMENT_ARG_LIST (RuntimeArgTypes2);
1925118611Snjl        }
1926118611Snjl        break;
1927118611Snjl
1928118611Snjl    default:
1929118611Snjl        break;
1930118611Snjl    }
1931118611Snjl
1932118611Snjl    return (AE_OK);
1933118611Snjl}
1934118611Snjl
1935118611Snjl
1936118611Snjl/*******************************************************************************
1937118611Snjl *
1938167802Sjkim * FUNCTION:    AnIsResultUsed
1939167802Sjkim *
1940167802Sjkim * PARAMETERS:  Op              - Parent op for the operator
1941167802Sjkim *
1942167802Sjkim * RETURN:      TRUE if result from this operation is actually consumed
1943167802Sjkim *
1944167802Sjkim * DESCRIPTION: Determine if the function result value from an operator is
1945167802Sjkim *              used.
1946167802Sjkim *
1947167802Sjkim ******************************************************************************/
1948167802Sjkim
1949167802SjkimBOOLEAN
1950167802SjkimAnIsResultUsed (
1951167802Sjkim    ACPI_PARSE_OBJECT       *Op)
1952167802Sjkim{
1953167802Sjkim    ACPI_PARSE_OBJECT       *Parent;
1954167802Sjkim
1955167802Sjkim
1956167802Sjkim    switch (Op->Asl.ParseOpcode)
1957167802Sjkim    {
1958167802Sjkim    case PARSEOP_INCREMENT:
1959167802Sjkim    case PARSEOP_DECREMENT:
1960167802Sjkim
1961167802Sjkim        /* These are standalone operators, no return value */
1962167802Sjkim
1963167802Sjkim        return (TRUE);
1964167802Sjkim
1965167802Sjkim    default:
1966167802Sjkim        break;
1967167802Sjkim    }
1968167802Sjkim
1969167802Sjkim    /* Examine parent to determine if the return value is used */
1970167802Sjkim
1971167802Sjkim    Parent = Op->Asl.Parent;
1972167802Sjkim    switch (Parent->Asl.ParseOpcode)
1973167802Sjkim    {
1974167802Sjkim    /* If/While - check if the operator is the predicate */
1975167802Sjkim
1976167802Sjkim    case PARSEOP_IF:
1977167802Sjkim    case PARSEOP_WHILE:
1978167802Sjkim
1979167802Sjkim        /* First child is the predicate */
1980167802Sjkim
1981167802Sjkim        if (Parent->Asl.Child == Op)
1982167802Sjkim        {
1983167802Sjkim            return (TRUE);
1984167802Sjkim        }
1985167802Sjkim        return (FALSE);
1986167802Sjkim
1987167802Sjkim    /* Not used if one of these is the parent */
1988167802Sjkim
1989167802Sjkim    case PARSEOP_METHOD:
1990167802Sjkim    case PARSEOP_DEFINITIONBLOCK:
1991167802Sjkim    case PARSEOP_ELSE:
1992167802Sjkim
1993167802Sjkim        return (FALSE);
1994167802Sjkim
1995167802Sjkim    default:
1996167802Sjkim        /* Any other type of parent means that the result is used */
1997167802Sjkim
1998167802Sjkim        return (TRUE);
1999167802Sjkim    }
2000167802Sjkim}
2001167802Sjkim
2002167802Sjkim
2003167802Sjkim/*******************************************************************************
2004167802Sjkim *
2005118611Snjl * FUNCTION:    AnOtherSemanticAnalysisWalkBegin
2006118611Snjl *
2007118611Snjl * PARAMETERS:  ASL_WALK_CALLBACK
2008118611Snjl *
2009118611Snjl * RETURN:      Status
2010118611Snjl *
2011167802Sjkim * DESCRIPTION: Descending callback for the analysis walk. Checks for
2012167802Sjkim *              miscellaneous issues in the code.
2013118611Snjl *
2014118611Snjl ******************************************************************************/
2015118611Snjl
2016118611SnjlACPI_STATUS
2017118611SnjlAnOtherSemanticAnalysisWalkBegin (
2018118611Snjl    ACPI_PARSE_OBJECT       *Op,
2019118611Snjl    UINT32                  Level,
2020118611Snjl    void                    *Context)
2021118611Snjl{
2022167802Sjkim    ACPI_PARSE_OBJECT       *ArgNode;
2023167802Sjkim    ACPI_PARSE_OBJECT       *PrevArgNode = NULL;
2024167802Sjkim    const ACPI_OPCODE_INFO  *OpInfo;
2025118611Snjl
2026167802Sjkim
2027167802Sjkim    OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode);
2028167802Sjkim
2029167802Sjkim    /*
2030167802Sjkim     * Determine if an execution class operator actually does something by
2031167802Sjkim     * checking if it has a target and/or the function return value is used.
2032167802Sjkim     * (Target is optional, so a standalone statement can actually do nothing.)
2033167802Sjkim     */
2034167802Sjkim    if ((OpInfo->Class == AML_CLASS_EXECUTE) &&
2035167802Sjkim        (OpInfo->Flags & AML_HAS_RETVAL) &&
2036167802Sjkim        (!AnIsResultUsed (Op)))
2037167802Sjkim    {
2038167802Sjkim        if (OpInfo->Flags & AML_HAS_TARGET)
2039167802Sjkim        {
2040167802Sjkim            /*
2041167802Sjkim             * Find the target node, it is always the last child. If the traget
2042167802Sjkim             * is not specified in the ASL, a default node of type Zero was
2043167802Sjkim             * created by the parser.
2044167802Sjkim             */
2045167802Sjkim            ArgNode = Op->Asl.Child;
2046167802Sjkim            while (ArgNode->Asl.Next)
2047167802Sjkim            {
2048167802Sjkim                PrevArgNode = ArgNode;
2049167802Sjkim                ArgNode = ArgNode->Asl.Next;
2050167802Sjkim            }
2051167802Sjkim
2052167802Sjkim            /* Divide() is the only weird case, it has two targets */
2053167802Sjkim
2054167802Sjkim            if (Op->Asl.AmlOpcode == AML_DIVIDE_OP)
2055167802Sjkim            {
2056167802Sjkim                if ((ArgNode->Asl.ParseOpcode == PARSEOP_ZERO) &&
2057167802Sjkim                    (PrevArgNode->Asl.ParseOpcode == PARSEOP_ZERO))
2058167802Sjkim                {
2059167802Sjkim                    AslError (ASL_WARNING, ASL_MSG_RESULT_NOT_USED, Op, Op->Asl.ExternalName);
2060167802Sjkim                }
2061167802Sjkim            }
2062167802Sjkim            else if (ArgNode->Asl.ParseOpcode == PARSEOP_ZERO)
2063167802Sjkim            {
2064167802Sjkim                AslError (ASL_WARNING, ASL_MSG_RESULT_NOT_USED, Op, Op->Asl.ExternalName);
2065167802Sjkim            }
2066167802Sjkim        }
2067167802Sjkim        else
2068167802Sjkim        {
2069167802Sjkim            /*
2070167802Sjkim             * Has no target and the result is not used. Only a couple opcodes
2071167802Sjkim             * can have this combination.
2072167802Sjkim             */
2073167802Sjkim            switch (Op->Asl.ParseOpcode)
2074167802Sjkim            {
2075167802Sjkim            case PARSEOP_ACQUIRE:
2076167802Sjkim            case PARSEOP_WAIT:
2077167802Sjkim                break;
2078167802Sjkim
2079167802Sjkim            default:
2080167802Sjkim                AslError (ASL_WARNING, ASL_MSG_RESULT_NOT_USED, Op, Op->Asl.ExternalName);
2081167802Sjkim                break;
2082167802Sjkim            }
2083167802Sjkim        }
2084167802Sjkim    }
2085167802Sjkim
2086167802Sjkim
2087167802Sjkim    /*
2088167802Sjkim     * Semantic checks for individual ASL operators
2089167802Sjkim     */
2090167802Sjkim    switch (Op->Asl.ParseOpcode)
2091167802Sjkim    {
2092167802Sjkim    case PARSEOP_ACQUIRE:
2093167802Sjkim    case PARSEOP_WAIT:
2094167802Sjkim        /*
2095167802Sjkim         * Emit a warning if the timeout parameter for these operators is not
2096167802Sjkim         * ACPI_WAIT_FOREVER, and the result value from the operator is not
2097167802Sjkim         * checked, meaning that a timeout could happen, but the code
2098167802Sjkim         * would not know about it.
2099167802Sjkim         */
2100167802Sjkim
2101167802Sjkim        /* First child is the namepath, 2nd child is timeout */
2102167802Sjkim
2103167802Sjkim        ArgNode = Op->Asl.Child;
2104167802Sjkim        ArgNode = ArgNode->Asl.Next;
2105167802Sjkim
2106167802Sjkim        /*
2107167802Sjkim         * Check for the WAIT_FOREVER case - defined by the ACPI spec to be
2108167802Sjkim         * 0xFFFF or greater
2109167802Sjkim         */
2110167802Sjkim        if (((ArgNode->Asl.ParseOpcode == PARSEOP_WORDCONST) ||
2111167802Sjkim             (ArgNode->Asl.ParseOpcode == PARSEOP_INTEGER))  &&
2112167802Sjkim             (ArgNode->Asl.Value.Integer >= (ACPI_INTEGER) ACPI_WAIT_FOREVER))
2113167802Sjkim        {
2114167802Sjkim            break;
2115167802Sjkim        }
2116167802Sjkim
2117167802Sjkim        /*
2118167802Sjkim         * The operation could timeout. If the return value is not used
2119167802Sjkim         * (indicates timeout occurred), issue a warning
2120167802Sjkim         */
2121167802Sjkim        if (!AnIsResultUsed (Op))
2122167802Sjkim        {
2123167802Sjkim            AslError (ASL_WARNING, ASL_MSG_TIMEOUT, ArgNode, Op->Asl.ExternalName);
2124167802Sjkim        }
2125167802Sjkim        break;
2126167802Sjkim
2127167802Sjkim    case PARSEOP_CREATEFIELD:
2128167802Sjkim        /*
2129167802Sjkim         * Check for a zero Length (NumBits) operand. NumBits is the 3rd operand
2130167802Sjkim         */
2131167802Sjkim        ArgNode = Op->Asl.Child;
2132167802Sjkim        ArgNode = ArgNode->Asl.Next;
2133167802Sjkim        ArgNode = ArgNode->Asl.Next;
2134167802Sjkim
2135167802Sjkim        if ((ArgNode->Asl.ParseOpcode == PARSEOP_ZERO) ||
2136167802Sjkim           ((ArgNode->Asl.ParseOpcode == PARSEOP_INTEGER) &&
2137167802Sjkim            (ArgNode->Asl.Value.Integer == 0)))
2138167802Sjkim        {
2139167802Sjkim            AslError (ASL_ERROR, ASL_MSG_NON_ZERO, ArgNode, NULL);
2140167802Sjkim        }
2141167802Sjkim        break;
2142167802Sjkim
2143167802Sjkim    default:
2144167802Sjkim        break;
2145167802Sjkim    }
2146167802Sjkim
2147118611Snjl    return AE_OK;
2148118611Snjl}
2149118611Snjl
2150118611Snjl
2151118611Snjl/*******************************************************************************
2152118611Snjl *
2153118611Snjl * FUNCTION:    AnOtherSemanticAnalysisWalkEnd
2154118611Snjl *
2155118611Snjl * PARAMETERS:  ASL_WALK_CALLBACK
2156118611Snjl *
2157118611Snjl * RETURN:      Status
2158118611Snjl *
2159167802Sjkim * DESCRIPTION: Ascending callback for analysis walk. Complete method
2160118611Snjl *              return analysis.
2161118611Snjl *
2162118611Snjl ******************************************************************************/
2163118611Snjl
2164118611SnjlACPI_STATUS
2165118611SnjlAnOtherSemanticAnalysisWalkEnd (
2166118611Snjl    ACPI_PARSE_OBJECT       *Op,
2167118611Snjl    UINT32                  Level,
2168118611Snjl    void                    *Context)
2169118611Snjl{
2170118611Snjl
2171118611Snjl    return AE_OK;
2172118611Snjl
2173118611Snjl}
2174151937Sjkim
2175151937Sjkim
2176151937Sjkim#ifdef ACPI_OBSOLETE_FUNCTIONS
2177151937Sjkim/*******************************************************************************
2178151937Sjkim *
2179151937Sjkim * FUNCTION:    AnMapBtypeToEtype
2180151937Sjkim *
2181151937Sjkim * PARAMETERS:  Btype               - Bitfield of ACPI types
2182151937Sjkim *
2183151937Sjkim * RETURN:      The Etype corresponding the the Btype
2184151937Sjkim *
2185151937Sjkim * DESCRIPTION: Convert a bitfield type to an encoded type
2186151937Sjkim *
2187151937Sjkim ******************************************************************************/
2188151937Sjkim
2189151937SjkimUINT32
2190151937SjkimAnMapBtypeToEtype (
2191151937Sjkim    UINT32              Btype)
2192151937Sjkim{
2193151937Sjkim    UINT32              i;
2194151937Sjkim    UINT32              Etype;
2195151937Sjkim
2196151937Sjkim
2197151937Sjkim    if (Btype == 0)
2198151937Sjkim    {
2199151937Sjkim        return 0;
2200151937Sjkim    }
2201151937Sjkim
2202151937Sjkim    Etype = 1;
2203151937Sjkim    for (i = 1; i < Btype; i *= 2)
2204151937Sjkim    {
2205151937Sjkim        Etype++;
2206151937Sjkim    }
2207151937Sjkim
2208151937Sjkim    return (Etype);
2209151937Sjkim}
2210151937Sjkim#endif
2211151937Sjkim
2212