aslpredef.c revision 218590
1204766Sjkim/******************************************************************************
2204766Sjkim *
3204766Sjkim * Module Name: aslpredef - support for ACPI predefined names
4204766Sjkim *
5204766Sjkim *****************************************************************************/
6204766Sjkim
7217365Sjkim/*
8217365Sjkim * Copyright (C) 2000 - 2011, Intel Corp.
9204766Sjkim * All rights reserved.
10204766Sjkim *
11217365Sjkim * Redistribution and use in source and binary forms, with or without
12217365Sjkim * modification, are permitted provided that the following conditions
13217365Sjkim * are met:
14217365Sjkim * 1. Redistributions of source code must retain the above copyright
15217365Sjkim *    notice, this list of conditions, and the following disclaimer,
16217365Sjkim *    without modification.
17217365Sjkim * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18217365Sjkim *    substantially similar to the "NO WARRANTY" disclaimer below
19217365Sjkim *    ("Disclaimer") and any redistribution must be conditioned upon
20217365Sjkim *    including a substantially similar Disclaimer requirement for further
21217365Sjkim *    binary redistribution.
22217365Sjkim * 3. Neither the names of the above-listed copyright holders nor the names
23217365Sjkim *    of any contributors may be used to endorse or promote products derived
24217365Sjkim *    from this software without specific prior written permission.
25204766Sjkim *
26217365Sjkim * Alternatively, this software may be distributed under the terms of the
27217365Sjkim * GNU General Public License ("GPL") version 2 as published by the Free
28217365Sjkim * Software Foundation.
29204766Sjkim *
30217365Sjkim * NO WARRANTY
31217365Sjkim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32217365Sjkim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33217365Sjkim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34217365Sjkim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35217365Sjkim * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36217365Sjkim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37217365Sjkim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38217365Sjkim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39217365Sjkim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40217365Sjkim * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41217365Sjkim * POSSIBILITY OF SUCH DAMAGES.
42217365Sjkim */
43204766Sjkim
44204766Sjkim#define ACPI_CREATE_PREDEFINED_TABLE
45204766Sjkim
46204773Sjkim#include <contrib/dev/acpica/compiler/aslcompiler.h>
47204766Sjkim#include "aslcompiler.y.h"
48204773Sjkim#include <contrib/dev/acpica/include/acpredef.h>
49204766Sjkim
50204766Sjkim
51204766Sjkim#define _COMPONENT          ACPI_COMPILER
52204766Sjkim        ACPI_MODULE_NAME    ("aslpredef")
53204766Sjkim
54204766Sjkim
55204766Sjkim/* Local prototypes */
56204766Sjkim
57218590Sjkimstatic void
58218590SjkimApCheckForUnexpectedReturnValue (
59218590Sjkim    ACPI_PARSE_OBJECT       *Op,
60218590Sjkim    ASL_METHOD_INFO         *MethodInfo);
61218590Sjkim
62204766Sjkimstatic UINT32
63204766SjkimApCheckForSpecialName (
64204766Sjkim    ACPI_PARSE_OBJECT       *Op,
65204766Sjkim    char                    *Name);
66204766Sjkim
67204766Sjkimstatic void
68204766SjkimApCheckObjectType (
69204766Sjkim    ACPI_PARSE_OBJECT       *Op,
70204766Sjkim    UINT32                  ExpectedBtypes);
71204766Sjkim
72204766Sjkimstatic void
73204766SjkimApGetExpectedTypes (
74204766Sjkim    char                    *Buffer,
75204766Sjkim    UINT32                  ExpectedBtypes);
76204766Sjkim
77204766Sjkim
78204766Sjkim/*
79204766Sjkim * Names for the types that can be returned by the predefined objects.
80204766Sjkim * Used for warning messages. Must be in the same order as the ACPI_RTYPEs
81204766Sjkim */
82204766Sjkimstatic const char   *AcpiRtypeNames[] =
83204766Sjkim{
84204766Sjkim    "/Integer",
85204766Sjkim    "/String",
86204766Sjkim    "/Buffer",
87204766Sjkim    "/Package",
88204766Sjkim    "/Reference",
89204766Sjkim};
90204766Sjkim
91204766Sjkim/*
92204766Sjkim * Predefined names for use in Resource Descriptors. These names do not
93204766Sjkim * appear in the global Predefined Name table (since these names never
94204766Sjkim * appear in actual AML byte code, only in the original ASL)
95204766Sjkim */
96204766Sjkimstatic const ACPI_PREDEFINED_INFO      ResourceNames[] = {
97204766Sjkim    {{"_ALN",     0,      0}},
98204766Sjkim    {{"_ASI",     0,      0}},
99204766Sjkim    {{"_ASZ",     0,      0}},
100204766Sjkim    {{"_ATT",     0,      0}},
101204766Sjkim    {{"_BAS",     0,      0}},
102204766Sjkim    {{"_BM_",     0,      0}},
103204766Sjkim    {{"_DEC",     0,      0}},
104204766Sjkim    {{"_GRA",     0,      0}},
105204766Sjkim    {{"_HE_",     0,      0}},
106204766Sjkim    {{"_INT",     0,      0}},
107204766Sjkim    {{"_LEN",     0,      0}},
108204766Sjkim    {{"_LL_",     0,      0}},
109204766Sjkim    {{"_MAF",     0,      0}},
110204766Sjkim    {{"_MAX",     0,      0}},
111204766Sjkim    {{"_MEM",     0,      0}},
112204766Sjkim    {{"_MIF",     0,      0}},
113204766Sjkim    {{"_MIN",     0,      0}},
114204766Sjkim    {{"_MTP",     0,      0}},
115204766Sjkim    {{"_RBO",     0,      0}},
116204766Sjkim    {{"_RBW",     0,      0}},
117204766Sjkim    {{"_RNG",     0,      0}},
118204766Sjkim    {{"_RT_",     0,      0}},  /* Acpi 3.0 */
119204766Sjkim    {{"_RW_",     0,      0}},
120204766Sjkim    {{"_SHR",     0,      0}},
121204766Sjkim    {{"_SIZ",     0,      0}},
122204766Sjkim    {{"_TRA",     0,      0}},
123204766Sjkim    {{"_TRS",     0,      0}},
124204766Sjkim    {{"_TSF",     0,      0}},  /* Acpi 3.0 */
125204766Sjkim    {{"_TTP",     0,      0}},
126204766Sjkim    {{"_TYP",     0,      0}},
127204766Sjkim    {{{0,0,0,0},  0,      0}}   /* Table terminator */
128204766Sjkim};
129204766Sjkim
130204766Sjkimstatic const ACPI_PREDEFINED_INFO      ScopeNames[] = {
131204766Sjkim    {{"_SB_",     0,      0}},
132204766Sjkim    {{"_SI_",     0,      0}},
133204766Sjkim    {{"_TZ_",     0,      0}},
134204766Sjkim    {{{0,0,0,0},  0,      0}}   /* Table terminator */
135204766Sjkim};
136204766Sjkim
137204766Sjkim
138204766Sjkim/*******************************************************************************
139204766Sjkim *
140204766Sjkim * FUNCTION:    ApCheckForPredefinedMethod
141204766Sjkim *
142204766Sjkim * PARAMETERS:  Op              - A parse node of type "METHOD".
143204766Sjkim *              MethodInfo      - Saved info about this method
144204766Sjkim *
145204766Sjkim * RETURN:      None
146204766Sjkim *
147204766Sjkim * DESCRIPTION: If method is a predefined name, check that the number of
148204766Sjkim *              arguments and the return type (returns a value or not)
149204766Sjkim *              is correct.
150204766Sjkim *
151204766Sjkim ******************************************************************************/
152204766Sjkim
153204766Sjkimvoid
154204766SjkimApCheckForPredefinedMethod (
155204766Sjkim    ACPI_PARSE_OBJECT       *Op,
156204766Sjkim    ASL_METHOD_INFO         *MethodInfo)
157204766Sjkim{
158204766Sjkim    UINT32                  Index;
159204766Sjkim    UINT32                  RequiredArgsCurrent;
160204766Sjkim    UINT32                  RequiredArgsOld;
161204766Sjkim
162204766Sjkim
163204766Sjkim    /* Check for a match against the predefined name list */
164204766Sjkim
165204766Sjkim    Index = ApCheckForPredefinedName (Op, Op->Asl.NameSeg);
166204766Sjkim
167204766Sjkim    switch (Index)
168204766Sjkim    {
169204766Sjkim    case ACPI_NOT_RESERVED_NAME:        /* No underscore or _Txx or _xxx name not matched */
170204766Sjkim    case ACPI_PREDEFINED_NAME:          /* Resource Name or reserved scope name */
171204766Sjkim    case ACPI_COMPILER_RESERVED_NAME:   /* A _Txx that was not emitted by compiler */
172204766Sjkim
173204766Sjkim        /* Just return, nothing to do */
174204766Sjkim        break;
175204766Sjkim
176204766Sjkim
177207344Sjkim    case ACPI_EVENT_RESERVED_NAME:      /* _Lxx/_Exx/_Wxx/_Qxx methods */
178204766Sjkim
179204766Sjkim        Gbl_ReservedMethods++;
180204766Sjkim
181207344Sjkim        /* NumArguments must be zero for all _Lxx/_Exx/_Wxx/_Qxx methods */
182204766Sjkim
183204766Sjkim        if (MethodInfo->NumArguments != 0)
184204766Sjkim        {
185209746Sjkim            sprintf (MsgBuffer, "%s requires %u", Op->Asl.ExternalName, 0);
186204766Sjkim
187204766Sjkim            AslError (ASL_WARNING, ASL_MSG_RESERVED_ARG_COUNT_HI, Op,
188204766Sjkim                MsgBuffer);
189204766Sjkim        }
190204766Sjkim        break;
191204766Sjkim
192204766Sjkim
193204766Sjkim    default:
194204766Sjkim        /*
195204766Sjkim         * Matched a predefined method name
196204766Sjkim         *
197204766Sjkim         * Validate the ASL-defined argument count. Allow two different legal
198204766Sjkim         * arg counts.
199204766Sjkim         */
200204766Sjkim        Gbl_ReservedMethods++;
201204766Sjkim
202204766Sjkim        RequiredArgsCurrent = PredefinedNames[Index].Info.ParamCount & 0x0F;
203204766Sjkim        RequiredArgsOld = PredefinedNames[Index].Info.ParamCount >> 4;
204204766Sjkim
205204766Sjkim        if ((MethodInfo->NumArguments != RequiredArgsCurrent) &&
206204766Sjkim            (MethodInfo->NumArguments != RequiredArgsOld))
207204766Sjkim        {
208209746Sjkim            sprintf (MsgBuffer, "%4.4s requires %u",
209204766Sjkim                PredefinedNames[Index].Info.Name, RequiredArgsCurrent);
210204766Sjkim
211204766Sjkim            if (MethodInfo->NumArguments > RequiredArgsCurrent)
212204766Sjkim            {
213204766Sjkim                AslError (ASL_WARNING, ASL_MSG_RESERVED_ARG_COUNT_HI, Op,
214204766Sjkim                    MsgBuffer);
215204766Sjkim            }
216204766Sjkim            else
217204766Sjkim            {
218204766Sjkim                AslError (ASL_WARNING, ASL_MSG_RESERVED_ARG_COUNT_LO, Op,
219204766Sjkim                    MsgBuffer);
220204766Sjkim            }
221204766Sjkim        }
222204766Sjkim
223204766Sjkim        /*
224204766Sjkim         * Check if method returns no value, but the predefined name is
225204766Sjkim         * required to return a value
226204766Sjkim         */
227204766Sjkim        if (MethodInfo->NumReturnNoValue &&
228204766Sjkim            PredefinedNames[Index].Info.ExpectedBtypes)
229204766Sjkim        {
230206117Sjkim            ApGetExpectedTypes (StringBuffer,
231206117Sjkim                PredefinedNames[Index].Info.ExpectedBtypes);
232204766Sjkim
233206117Sjkim            sprintf (MsgBuffer, "%s required for %4.4s",
234206117Sjkim                StringBuffer, PredefinedNames[Index].Info.Name);
235206117Sjkim
236204766Sjkim            AslError (ASL_WARNING, ASL_MSG_RESERVED_RETURN_VALUE, Op,
237204766Sjkim                MsgBuffer);
238204766Sjkim        }
239204766Sjkim        break;
240204766Sjkim    }
241204766Sjkim}
242204766Sjkim
243204766Sjkim
244204766Sjkim/*******************************************************************************
245204766Sjkim *
246218590Sjkim * FUNCTION:    ApCheckForUnexpectedReturnValue
247218590Sjkim *
248218590Sjkim * PARAMETERS:  Op              - A parse node of type "RETURN".
249218590Sjkim *              MethodInfo      - Saved info about this method
250218590Sjkim *
251218590Sjkim * RETURN:      None
252218590Sjkim *
253218590Sjkim * DESCRIPTION: Check for an unexpected return value from a predefined method.
254218590Sjkim *              Invoked for predefined methods that are defined to not return
255218590Sjkim *              any value. If there is a return value, issue a remark, since
256218590Sjkim *              the ASL writer may be confused as to the method definition
257218590Sjkim *              and/or functionality.
258218590Sjkim *
259218590Sjkim * Note: We ignore all return values of "Zero", since this is what a standalone
260218590Sjkim *       Return() statement will always generate -- so we ignore it here --
261218590Sjkim *       i.e., there is no difference between Return() and Return(Zero).
262218590Sjkim *       Also, a null Return() will be disassembled to return(Zero) -- so, we
263218590Sjkim *       don't want to generate extraneous remarks/warnings for a disassembled
264218590Sjkim *       ASL file.
265218590Sjkim *
266218590Sjkim ******************************************************************************/
267218590Sjkim
268218590Sjkimstatic void
269218590SjkimApCheckForUnexpectedReturnValue (
270218590Sjkim    ACPI_PARSE_OBJECT       *Op,
271218590Sjkim    ASL_METHOD_INFO         *MethodInfo)
272218590Sjkim{
273218590Sjkim    ACPI_PARSE_OBJECT       *ReturnValueOp;
274218590Sjkim
275218590Sjkim
276218590Sjkim    /* Ignore Return() and Return(Zero) (they are the same) */
277218590Sjkim
278218590Sjkim    ReturnValueOp = Op->Asl.Child;
279218590Sjkim    if (ReturnValueOp->Asl.ParseOpcode == PARSEOP_ZERO)
280218590Sjkim    {
281218590Sjkim        return;
282218590Sjkim    }
283218590Sjkim
284218590Sjkim    /* We have a valid return value, but the reserved name did not expect it */
285218590Sjkim
286218590Sjkim    AslError (ASL_WARNING, ASL_MSG_RESERVED_NO_RETURN_VAL,
287218590Sjkim        Op, MethodInfo->Op->Asl.ExternalName);
288218590Sjkim}
289218590Sjkim
290218590Sjkim
291218590Sjkim/*******************************************************************************
292218590Sjkim *
293206117Sjkim * FUNCTION:    ApCheckPredefinedReturnValue
294206117Sjkim *
295206117Sjkim * PARAMETERS:  Op              - A parse node of type "RETURN".
296206117Sjkim *              MethodInfo      - Saved info about this method
297206117Sjkim *
298206117Sjkim * RETURN:      None
299206117Sjkim *
300206117Sjkim * DESCRIPTION: If method is a predefined name, attempt to validate the return
301206117Sjkim *              value. Only "static" types can be validated - a simple return
302206117Sjkim *              of an integer/string/buffer/package or a named reference to
303206117Sjkim *              a static object. Values such as a Localx or Argx or a control
304218590Sjkim *              method invocation are not checked. Issue a warning if there is
305218590Sjkim *              a valid return value, but the reserved method defines no
306218590Sjkim *              return value.
307206117Sjkim *
308206117Sjkim ******************************************************************************/
309206117Sjkim
310206117Sjkimvoid
311206117SjkimApCheckPredefinedReturnValue (
312206117Sjkim    ACPI_PARSE_OBJECT       *Op,
313206117Sjkim    ASL_METHOD_INFO         *MethodInfo)
314206117Sjkim{
315206117Sjkim    UINT32                  Index;
316206117Sjkim    ACPI_PARSE_OBJECT       *ReturnValueOp;
317206117Sjkim
318206117Sjkim
319206117Sjkim    /* Check parent method for a match against the predefined name list */
320206117Sjkim
321206117Sjkim    Index = ApCheckForPredefinedName (MethodInfo->Op,
322206117Sjkim                MethodInfo->Op->Asl.NameSeg);
323206117Sjkim
324206117Sjkim    switch (Index)
325206117Sjkim    {
326218590Sjkim    case ACPI_EVENT_RESERVED_NAME:      /* _Lxx/_Exx/_Wxx/_Qxx methods */
327218590Sjkim
328218590Sjkim        /* No return value expected, warn if there is one */
329218590Sjkim
330218590Sjkim        ApCheckForUnexpectedReturnValue (Op, MethodInfo);
331218590Sjkim        return;
332218590Sjkim
333206117Sjkim    case ACPI_NOT_RESERVED_NAME:        /* No underscore or _Txx or _xxx name not matched */
334206117Sjkim    case ACPI_PREDEFINED_NAME:          /* Resource Name or reserved scope name */
335206117Sjkim    case ACPI_COMPILER_RESERVED_NAME:   /* A _Txx that was not emitted by compiler */
336206117Sjkim
337206117Sjkim        /* Just return, nothing to do */
338206117Sjkim        return;
339206117Sjkim
340207344Sjkim    default: /* A standard predefined ACPI name */
341206117Sjkim
342206117Sjkim        if (!PredefinedNames[Index].Info.ExpectedBtypes)
343206117Sjkim        {
344218590Sjkim            /* No return value expected, warn if there is one */
345218590Sjkim
346218590Sjkim            ApCheckForUnexpectedReturnValue (Op, MethodInfo);
347206117Sjkim            return;
348206117Sjkim        }
349206117Sjkim
350206117Sjkim        /* Get the object returned, it is the next argument */
351206117Sjkim
352206117Sjkim        ReturnValueOp = Op->Asl.Child;
353206117Sjkim        switch (ReturnValueOp->Asl.ParseOpcode)
354206117Sjkim        {
355206117Sjkim        case PARSEOP_ZERO:
356206117Sjkim        case PARSEOP_ONE:
357206117Sjkim        case PARSEOP_ONES:
358206117Sjkim        case PARSEOP_INTEGER:
359206117Sjkim        case PARSEOP_STRING_LITERAL:
360206117Sjkim        case PARSEOP_BUFFER:
361206117Sjkim        case PARSEOP_PACKAGE:
362206117Sjkim
363206117Sjkim            /* Static data return object - check against expected type */
364206117Sjkim
365206117Sjkim            ApCheckObjectType (ReturnValueOp,
366206117Sjkim                PredefinedNames[Index].Info.ExpectedBtypes);
367206117Sjkim            break;
368206117Sjkim
369206117Sjkim        default:
370206117Sjkim
371206117Sjkim            /*
372206117Sjkim             * All other ops are very difficult or impossible to typecheck at
373206117Sjkim             * compile time. These include all Localx, Argx, and method
374206117Sjkim             * invocations. Also, NAMESEG and NAMESTRING because the type of
375206117Sjkim             * any named object can be changed at runtime (for example,
376206117Sjkim             * CopyObject will change the type of the target object.)
377206117Sjkim             */
378206117Sjkim            break;
379206117Sjkim        }
380206117Sjkim    }
381206117Sjkim}
382206117Sjkim
383206117Sjkim
384206117Sjkim/*******************************************************************************
385206117Sjkim *
386204766Sjkim * FUNCTION:    ApCheckForPredefinedObject
387204766Sjkim *
388204766Sjkim * PARAMETERS:  Op              - A parse node
389204766Sjkim *              Name            - The ACPI name to be checked
390204766Sjkim *
391204766Sjkim * RETURN:      None
392204766Sjkim *
393204766Sjkim * DESCRIPTION: Check for a predefined name for a static object (created via
394204766Sjkim *              the ASL Name operator). If it is a predefined ACPI name, ensure
395204766Sjkim *              that the name does not require any arguments (which would
396204766Sjkim *              require a control method implemenation of the name), and that
397204766Sjkim *              the type of the object is one of the expected types for the
398204766Sjkim *              predefined name.
399204766Sjkim *
400204766Sjkim ******************************************************************************/
401204766Sjkim
402204766Sjkimvoid
403204766SjkimApCheckForPredefinedObject (
404204766Sjkim    ACPI_PARSE_OBJECT       *Op,
405204766Sjkim    char                    *Name)
406204766Sjkim{
407204766Sjkim    UINT32                  Index;
408204766Sjkim
409204766Sjkim
410204766Sjkim    /*
411204766Sjkim     * Check for a real predefined name -- not a resource descriptor name
412204766Sjkim     * or a predefined scope name
413204766Sjkim     */
414204766Sjkim    Index = ApCheckForPredefinedName (Op, Name);
415207344Sjkim
416207344Sjkim    switch (Index)
417204766Sjkim    {
418207344Sjkim    case ACPI_NOT_RESERVED_NAME:        /* No underscore or _Txx or _xxx name not matched */
419207344Sjkim    case ACPI_PREDEFINED_NAME:          /* Resource Name or reserved scope name */
420207344Sjkim    case ACPI_COMPILER_RESERVED_NAME:   /* A _Txx that was not emitted by compiler */
421207344Sjkim
422207344Sjkim        /* Nothing to do */
423204766Sjkim        return;
424204766Sjkim
425207344Sjkim    case ACPI_EVENT_RESERVED_NAME:      /* _Lxx/_Exx/_Wxx/_Qxx methods */
426207344Sjkim
427204766Sjkim        /*
428207344Sjkim         * These names must be control methods, by definition in ACPI spec.
429207344Sjkim         * Also because they are defined to return no value. None of them
430207344Sjkim         * require any arguments.
431204766Sjkim         */
432204766Sjkim        AslError (ASL_ERROR, ASL_MSG_RESERVED_METHOD, Op,
433207344Sjkim            "with zero arguments");
434207344Sjkim        return;
435204766Sjkim
436207344Sjkim    default: /* A standard predefined ACPI name */
437204766Sjkim
438207344Sjkim        /*
439207344Sjkim         * If this predefined name requires input arguments, then
440207344Sjkim         * it must be implemented as a control method
441207344Sjkim         */
442207344Sjkim        if (PredefinedNames[Index].Info.ParamCount > 0)
443207344Sjkim        {
444207344Sjkim            AslError (ASL_ERROR, ASL_MSG_RESERVED_METHOD, Op,
445207344Sjkim                "with arguments");
446207344Sjkim            return;
447207344Sjkim        }
448207344Sjkim
449207344Sjkim        /*
450207344Sjkim         * If no return value is expected from this predefined name, then
451207344Sjkim         * it follows that it must be implemented as a control method
452207344Sjkim         * (with zero args, because the args > 0 case was handled above)
453207344Sjkim         * Examples are: _DIS, _INI, _IRC, _OFF, _ON, _PSx
454207344Sjkim         */
455207344Sjkim        if (!PredefinedNames[Index].Info.ExpectedBtypes)
456207344Sjkim        {
457207344Sjkim            AslError (ASL_ERROR, ASL_MSG_RESERVED_METHOD, Op,
458207344Sjkim                "with zero arguments");
459207344Sjkim            return;
460207344Sjkim        }
461207344Sjkim
462207344Sjkim        /* Typecheck the actual object, it is the next argument */
463207344Sjkim
464207344Sjkim        ApCheckObjectType (Op->Asl.Child->Asl.Next,
465207344Sjkim            PredefinedNames[Index].Info.ExpectedBtypes);
466207344Sjkim        return;
467207344Sjkim    }
468204766Sjkim}
469204766Sjkim
470204766Sjkim
471204766Sjkim/*******************************************************************************
472204766Sjkim *
473204766Sjkim * FUNCTION:    ApCheckForPredefinedName
474204766Sjkim *
475204766Sjkim * PARAMETERS:  Op              - A parse node
476204766Sjkim *              Name            - NameSeg to check
477204766Sjkim *
478204766Sjkim * RETURN:      None
479204766Sjkim *
480204766Sjkim * DESCRIPTION: Check a NameSeg against the reserved list.
481204766Sjkim *
482204766Sjkim ******************************************************************************/
483204766Sjkim
484204766SjkimUINT32
485204766SjkimApCheckForPredefinedName (
486204766Sjkim    ACPI_PARSE_OBJECT       *Op,
487204766Sjkim    char                    *Name)
488204766Sjkim{
489204766Sjkim    UINT32                  i;
490204766Sjkim
491204766Sjkim
492204766Sjkim    if (Name[0] == 0)
493204766Sjkim    {
494204766Sjkim        AcpiOsPrintf ("Found a null name, external = %s\n",
495204766Sjkim            Op->Asl.ExternalName);
496204766Sjkim    }
497204766Sjkim
498204766Sjkim    /* All reserved names are prefixed with a single underscore */
499204766Sjkim
500204766Sjkim    if (Name[0] != '_')
501204766Sjkim    {
502204766Sjkim        return (ACPI_NOT_RESERVED_NAME);
503204766Sjkim    }
504204766Sjkim
505204766Sjkim    /* Check for a standard predefined method name */
506204766Sjkim
507204766Sjkim    for (i = 0; PredefinedNames[i].Info.Name[0]; i++)
508204766Sjkim    {
509204766Sjkim        if (ACPI_COMPARE_NAME (Name, PredefinedNames[i].Info.Name))
510204766Sjkim        {
511204766Sjkim            /* Return index into predefined array */
512204766Sjkim            return (i);
513204766Sjkim        }
514204766Sjkim    }
515204766Sjkim
516204766Sjkim    /* Check for resource names and predefined scope names */
517204766Sjkim
518204766Sjkim    for (i = 0; ResourceNames[i].Info.Name[0]; i++)
519204766Sjkim    {
520204766Sjkim        if (ACPI_COMPARE_NAME (Name, ResourceNames[i].Info.Name))
521204766Sjkim        {
522204766Sjkim            return (ACPI_PREDEFINED_NAME);
523204766Sjkim        }
524204766Sjkim    }
525204766Sjkim
526204766Sjkim    for (i = 0; ScopeNames[i].Info.Name[0]; i++)
527204766Sjkim    {
528204766Sjkim        if (ACPI_COMPARE_NAME (Name, ScopeNames[i].Info.Name))
529204766Sjkim        {
530204766Sjkim            return (ACPI_PREDEFINED_NAME);
531204766Sjkim        }
532204766Sjkim    }
533204766Sjkim
534207344Sjkim    /* Check for _Lxx/_Exx/_Wxx/_Qxx/_T_x. Warning if unknown predefined name */
535204766Sjkim
536204766Sjkim    return (ApCheckForSpecialName (Op, Name));
537204766Sjkim}
538204766Sjkim
539204766Sjkim
540204766Sjkim/*******************************************************************************
541204766Sjkim *
542204766Sjkim * FUNCTION:    ApCheckForSpecialName
543204766Sjkim *
544204766Sjkim * PARAMETERS:  Op              - A parse node
545204766Sjkim *              Name            - NameSeg to check
546204766Sjkim *
547204766Sjkim * RETURN:      None
548204766Sjkim *
549206117Sjkim * DESCRIPTION: Check for the "special" predefined names -
550207344Sjkim *              _Lxx, _Exx, _Qxx, _Wxx, and _T_x
551204766Sjkim *
552204766Sjkim ******************************************************************************/
553204766Sjkim
554204766Sjkimstatic UINT32
555204766SjkimApCheckForSpecialName (
556204766Sjkim    ACPI_PARSE_OBJECT       *Op,
557204766Sjkim    char                    *Name)
558204766Sjkim{
559204766Sjkim
560204766Sjkim    /*
561207344Sjkim     * Check for the "special" predefined names. We already know that the
562207344Sjkim     * first character is an underscore.
563204766Sjkim     *   GPE:  _Lxx
564204766Sjkim     *   GPE:  _Exx
565207344Sjkim     *   GPE:  _Wxx
566204766Sjkim     *   EC:   _Qxx
567204766Sjkim     */
568204766Sjkim    if ((Name[1] == 'L') ||
569204766Sjkim        (Name[1] == 'E') ||
570207344Sjkim        (Name[1] == 'W') ||
571204766Sjkim        (Name[1] == 'Q'))
572204766Sjkim    {
573204766Sjkim        /* The next two characters must be hex digits */
574204766Sjkim
575204766Sjkim        if ((isxdigit ((int) Name[2])) &&
576204766Sjkim            (isxdigit ((int) Name[3])))
577204766Sjkim        {
578204766Sjkim            return (ACPI_EVENT_RESERVED_NAME);
579204766Sjkim        }
580204766Sjkim    }
581204766Sjkim
582204766Sjkim    /* Check for the names reserved for the compiler itself: _T_x */
583204766Sjkim
584204766Sjkim    else if ((Op->Asl.ExternalName[1] == 'T') &&
585204766Sjkim             (Op->Asl.ExternalName[2] == '_'))
586204766Sjkim    {
587204766Sjkim        /* Ignore if actually emitted by the compiler */
588204766Sjkim
589204766Sjkim        if (Op->Asl.CompileFlags & NODE_COMPILER_EMITTED)
590204766Sjkim        {
591204766Sjkim            return (ACPI_NOT_RESERVED_NAME);
592204766Sjkim        }
593204766Sjkim
594204766Sjkim        /*
595204766Sjkim         * Was not actually emitted by the compiler. This is a special case,
596204766Sjkim         * however. If the ASL code being compiled was the result of a
597204766Sjkim         * dissasembly, it may possibly contain valid compiler-emitted names
598204766Sjkim         * of the form "_T_x". We don't want to issue an error or even a
599204766Sjkim         * warning and force the user to manually change the names. So, we
600204766Sjkim         * will issue a remark instead.
601204766Sjkim         */
602204766Sjkim        AslError (ASL_REMARK, ASL_MSG_COMPILER_RESERVED, Op, Op->Asl.ExternalName);
603204766Sjkim        return (ACPI_COMPILER_RESERVED_NAME);
604204766Sjkim    }
605204766Sjkim
606204766Sjkim    /*
607204766Sjkim     * The name didn't match any of the known predefined names. Flag it as a
608204766Sjkim     * warning, since the entire namespace starting with an underscore is
609204766Sjkim     * reserved by the ACPI spec.
610204766Sjkim     */
611204766Sjkim    AslError (ASL_WARNING, ASL_MSG_UNKNOWN_RESERVED_NAME, Op,
612204766Sjkim        Op->Asl.ExternalName);
613204766Sjkim
614204766Sjkim    return (ACPI_NOT_RESERVED_NAME);
615204766Sjkim}
616204766Sjkim
617204766Sjkim
618204766Sjkim/*******************************************************************************
619204766Sjkim *
620204766Sjkim * FUNCTION:    ApCheckObjectType
621204766Sjkim *
622206117Sjkim * PARAMETERS:  Op              - Current parse node
623204766Sjkim *              ExpectedBtypes  - Bitmap of expected return type(s)
624204766Sjkim *
625204766Sjkim * RETURN:      None
626204766Sjkim *
627204766Sjkim * DESCRIPTION: Check if the object type is one of the types that is expected
628204766Sjkim *              by the predefined name. Only a limited number of object types
629204766Sjkim *              can be returned by the predefined names.
630204766Sjkim *
631204766Sjkim ******************************************************************************/
632204766Sjkim
633204766Sjkimstatic void
634204766SjkimApCheckObjectType (
635204766Sjkim    ACPI_PARSE_OBJECT       *Op,
636204766Sjkim    UINT32                  ExpectedBtypes)
637204766Sjkim{
638204766Sjkim    UINT32                  ReturnBtype;
639204766Sjkim
640204766Sjkim
641204766Sjkim    switch (Op->Asl.ParseOpcode)
642204766Sjkim    {
643206117Sjkim    case PARSEOP_ZERO:
644206117Sjkim    case PARSEOP_ONE:
645206117Sjkim    case PARSEOP_ONES:
646204766Sjkim    case PARSEOP_INTEGER:
647204766Sjkim        ReturnBtype = ACPI_RTYPE_INTEGER;
648204766Sjkim        break;
649204766Sjkim
650204766Sjkim    case PARSEOP_BUFFER:
651204766Sjkim        ReturnBtype = ACPI_RTYPE_BUFFER;
652204766Sjkim        break;
653204766Sjkim
654204766Sjkim    case PARSEOP_STRING_LITERAL:
655204766Sjkim        ReturnBtype = ACPI_RTYPE_STRING;
656204766Sjkim        break;
657204766Sjkim
658204766Sjkim    case PARSEOP_PACKAGE:
659204766Sjkim        ReturnBtype = ACPI_RTYPE_PACKAGE;
660204766Sjkim        break;
661204766Sjkim
662204766Sjkim    default:
663204766Sjkim        /* Not one of the supported object types */
664206117Sjkim
665204766Sjkim        goto TypeErrorExit;
666204766Sjkim    }
667204766Sjkim
668206117Sjkim    /* Exit if the object is one of the expected types */
669204766Sjkim
670204766Sjkim    if (ReturnBtype & ExpectedBtypes)
671204766Sjkim    {
672204766Sjkim        return;
673204766Sjkim    }
674204766Sjkim
675204766Sjkim
676204766SjkimTypeErrorExit:
677204766Sjkim
678204766Sjkim    /* Format the expected types and emit an error message */
679204766Sjkim
680206117Sjkim    ApGetExpectedTypes (StringBuffer, ExpectedBtypes);
681204766Sjkim
682206117Sjkim    sprintf (MsgBuffer, "found %s, requires %s",
683206117Sjkim        UtGetOpName (Op->Asl.ParseOpcode), StringBuffer);
684206117Sjkim
685204766Sjkim    AslError (ASL_ERROR, ASL_MSG_RESERVED_OPERAND_TYPE, Op,
686206117Sjkim        MsgBuffer);
687204766Sjkim}
688204766Sjkim
689204766Sjkim
690204766Sjkim/*******************************************************************************
691204766Sjkim *
692204766Sjkim * FUNCTION:    ApDisplayReservedNames
693204766Sjkim *
694204766Sjkim * PARAMETERS:  None
695204766Sjkim *
696204766Sjkim * RETURN:      None
697204766Sjkim *
698204766Sjkim * DESCRIPTION: Dump information about the ACPI predefined names and predefined
699204766Sjkim *              resource descriptor names.
700204766Sjkim *
701204766Sjkim ******************************************************************************/
702204766Sjkim
703204766Sjkimvoid
704204766SjkimApDisplayReservedNames (
705204766Sjkim    void)
706204766Sjkim{
707204766Sjkim    const ACPI_PREDEFINED_INFO  *ThisName;
708204766Sjkim    char                        TypeBuffer[48]; /* Room for 5 types */
709204766Sjkim    UINT32                      Count;
710204766Sjkim
711204766Sjkim
712204766Sjkim    /*
713204766Sjkim     * Predefined names/methods
714204766Sjkim     */
715204766Sjkim    printf ("\nPredefined Name Information\n\n");
716204766Sjkim
717204766Sjkim    Count = 0;
718204766Sjkim    ThisName = PredefinedNames;
719204766Sjkim    while (ThisName->Info.Name[0])
720204766Sjkim    {
721209746Sjkim        printf ("%4.4s    Requires %u arguments, ",
722204766Sjkim            ThisName->Info.Name, ThisName->Info.ParamCount & 0x0F);
723204766Sjkim
724204766Sjkim        if (ThisName->Info.ExpectedBtypes)
725204766Sjkim        {
726204766Sjkim            ApGetExpectedTypes (TypeBuffer, ThisName->Info.ExpectedBtypes);
727204766Sjkim            printf ("Must return: %s\n", TypeBuffer);
728204766Sjkim        }
729204766Sjkim        else
730204766Sjkim        {
731204766Sjkim            printf ("No return value\n");
732204766Sjkim        }
733204766Sjkim
734204766Sjkim        /*
735204766Sjkim         * Skip next entry in the table if this name returns a Package
736204766Sjkim         * (next entry contains the package info)
737204766Sjkim         */
738204766Sjkim        if (ThisName->Info.ExpectedBtypes & ACPI_RTYPE_PACKAGE)
739204766Sjkim        {
740204766Sjkim            ThisName++;
741204766Sjkim        }
742204766Sjkim
743204766Sjkim        Count++;
744204766Sjkim        ThisName++;
745204766Sjkim    }
746204766Sjkim
747204766Sjkim    printf ("%u Predefined Names are recognized\n", Count);
748204766Sjkim
749204766Sjkim    /*
750204766Sjkim     * Resource Descriptor names
751204766Sjkim     */
752204766Sjkim    printf ("\nResource Descriptor Predefined Names\n\n");
753204766Sjkim
754204766Sjkim    Count = 0;
755204766Sjkim    ThisName = ResourceNames;
756204766Sjkim    while (ThisName->Info.Name[0])
757204766Sjkim    {
758204766Sjkim        printf ("%4.4s    Resource Descriptor\n", ThisName->Info.Name);
759204766Sjkim        Count++;
760204766Sjkim        ThisName++;
761204766Sjkim    }
762204766Sjkim
763204766Sjkim    printf ("%u Resource Descriptor Names are recognized\n", Count);
764204766Sjkim
765204766Sjkim    /*
766204766Sjkim     * Predefined scope names
767204766Sjkim     */
768204766Sjkim    printf ("\nPredefined Scope Names\n\n");
769204766Sjkim
770204766Sjkim    ThisName = ScopeNames;
771204766Sjkim    while (ThisName->Info.Name[0])
772204766Sjkim    {
773204766Sjkim        printf ("%4.4s    Scope\n", ThisName->Info.Name);
774204766Sjkim        ThisName++;
775204766Sjkim    }
776204766Sjkim}
777204766Sjkim
778204766Sjkim
779204766Sjkim/*******************************************************************************
780204766Sjkim *
781204766Sjkim * FUNCTION:    ApGetExpectedTypes
782204766Sjkim *
783204766Sjkim * PARAMETERS:  Buffer              - Where the formatted string is returned
784204766Sjkim *              ExpectedBTypes      - Bitfield of expected data types
785204766Sjkim *
786204766Sjkim * RETURN:      None, formatted string
787204766Sjkim *
788204766Sjkim * DESCRIPTION: Format the expected object types into a printable string.
789204766Sjkim *
790204766Sjkim ******************************************************************************/
791204766Sjkim
792204766Sjkimstatic void
793204766SjkimApGetExpectedTypes (
794204766Sjkim    char                        *Buffer,
795204766Sjkim    UINT32                      ExpectedBtypes)
796204766Sjkim{
797204766Sjkim    UINT32                      ThisRtype;
798204766Sjkim    UINT32                      i;
799204766Sjkim    UINT32                      j;
800204766Sjkim
801204766Sjkim
802204766Sjkim    j = 1;
803204766Sjkim    Buffer[0] = 0;
804204766Sjkim    ThisRtype = ACPI_RTYPE_INTEGER;
805204766Sjkim
806204766Sjkim    for (i = 0; i < ACPI_NUM_RTYPES; i++)
807204766Sjkim    {
808204766Sjkim        /* If one of the expected types, concatenate the name of this type */
809204766Sjkim
810204766Sjkim        if (ExpectedBtypes & ThisRtype)
811204766Sjkim        {
812204766Sjkim            ACPI_STRCAT (Buffer, &AcpiRtypeNames[i][j]);
813204766Sjkim            j = 0;              /* Use name separator from now on */
814204766Sjkim        }
815204766Sjkim        ThisRtype <<= 1;    /* Next Rtype */
816204766Sjkim    }
817204766Sjkim}
818204766Sjkim
819