xref: /freebsd/sys/contrib/dev/acpica/compiler/aslpredef.c (revision 11c5cac53f6cc9a2d94cb6f58728b2655e92d3a5)
1 /******************************************************************************
2  *
3  * Module Name: aslpredef - support for ACPI predefined names
4  *
5  *****************************************************************************/
6 
7 /*
8  * Copyright (C) 2000 - 2013, Intel Corp.
9  * All rights reserved.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions, and the following disclaimer,
16  *    without modification.
17  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18  *    substantially similar to the "NO WARRANTY" disclaimer below
19  *    ("Disclaimer") and any redistribution must be conditioned upon
20  *    including a substantially similar Disclaimer requirement for further
21  *    binary redistribution.
22  * 3. Neither the names of the above-listed copyright holders nor the names
23  *    of any contributors may be used to endorse or promote products derived
24  *    from this software without specific prior written permission.
25  *
26  * Alternatively, this software may be distributed under the terms of the
27  * GNU General Public License ("GPL") version 2 as published by the Free
28  * Software Foundation.
29  *
30  * NO WARRANTY
31  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41  * POSSIBILITY OF SUCH DAMAGES.
42  */
43 
44 #define ACPI_CREATE_PREDEFINED_TABLE
45 
46 #include <contrib/dev/acpica/compiler/aslcompiler.h>
47 #include "aslcompiler.y.h"
48 #include <contrib/dev/acpica/include/acpredef.h>
49 #include <contrib/dev/acpica/include/acnamesp.h>
50 
51 
52 #define _COMPONENT          ACPI_COMPILER
53         ACPI_MODULE_NAME    ("aslpredef")
54 
55 
56 /* Local prototypes */
57 
58 static void
59 ApCheckForUnexpectedReturnValue (
60     ACPI_PARSE_OBJECT       *Op,
61     ASL_METHOD_INFO         *MethodInfo);
62 
63 static UINT32
64 ApCheckForSpecialName (
65     ACPI_PARSE_OBJECT       *Op,
66     char                    *Name);
67 
68 static void
69 ApGetExpectedTypes (
70     char                    *Buffer,
71     UINT32                  ExpectedBtypes);
72 
73 
74 /*
75  * Names for the types that can be returned by the predefined objects.
76  * Used for warning messages. Must be in the same order as the ACPI_RTYPEs
77  */
78 static const char   *AcpiRtypeNames[] =
79 {
80     "/Integer",
81     "/String",
82     "/Buffer",
83     "/Package",
84     "/Reference",
85 };
86 
87 /*
88  * Predefined names for use in Resource Descriptors. These names do not
89  * appear in the global Predefined Name table (since these names never
90  * appear in actual AML byte code, only in the original ASL)
91  */
92 static const ACPI_PREDEFINED_INFO      ResourceNames[] = {
93     {{"_ALN",     0,      0}},
94     {{"_ASI",     0,      0}},
95     {{"_ASZ",     0,      0}},
96     {{"_ATT",     0,      0}},
97     {{"_BAS",     0,      0}},
98     {{"_BM_",     0,      0}},
99     {{"_DBT",     0,      0}},  /* Acpi 5.0 */
100     {{"_DEC",     0,      0}},
101     {{"_DPL",     0,      0}},  /* Acpi 5.0 */
102     {{"_DRS",     0,      0}},  /* Acpi 5.0 */
103     {{"_END",     0,      0}},  /* Acpi 5.0 */
104     {{"_FLC",     0,      0}},  /* Acpi 5.0 */
105     {{"_GRA",     0,      0}},
106     {{"_HE_",     0,      0}},
107     {{"_INT",     0,      0}},
108     {{"_IOR",     0,      0}},  /* Acpi 5.0 */
109     {{"_LEN",     0,      0}},
110     {{"_LIN",     0,      0}},  /* Acpi 5.0 */
111     {{"_LL_",     0,      0}},
112     {{"_MAF",     0,      0}},
113     {{"_MAX",     0,      0}},
114     {{"_MEM",     0,      0}},
115     {{"_MIF",     0,      0}},
116     {{"_MIN",     0,      0}},
117     {{"_MOD",     0,      0}},  /* Acpi 5.0 */
118     {{"_MTP",     0,      0}},
119     {{"_PAR",     0,      0}},  /* Acpi 5.0 */
120     {{"_PHA",     0,      0}},  /* Acpi 5.0 */
121     {{"_PIN",     0,      0}},  /* Acpi 5.0 */
122     {{"_PPI",     0,      0}},  /* Acpi 5.0 */
123     {{"_POL",     0,      0}},  /* Acpi 5.0 */
124     {{"_RBO",     0,      0}},
125     {{"_RBW",     0,      0}},
126     {{"_RNG",     0,      0}},
127     {{"_RT_",     0,      0}},  /* Acpi 3.0 */
128     {{"_RW_",     0,      0}},
129     {{"_RXL",     0,      0}},  /* Acpi 5.0 */
130     {{"_SHR",     0,      0}},
131     {{"_SIZ",     0,      0}},
132     {{"_SLV",     0,      0}},  /* Acpi 5.0 */
133     {{"_SPE",     0,      0}},  /* Acpi 5.0 */
134     {{"_STB",     0,      0}},  /* Acpi 5.0 */
135     {{"_TRA",     0,      0}},
136     {{"_TRS",     0,      0}},
137     {{"_TSF",     0,      0}},  /* Acpi 3.0 */
138     {{"_TTP",     0,      0}},
139     {{"_TXL",     0,      0}},  /* Acpi 5.0 */
140     {{"_TYP",     0,      0}},
141     {{"_VEN",     0,      0}},  /* Acpi 5.0 */
142     {{{0,0,0,0},  0,      0}}   /* Table terminator */
143 };
144 
145 static const ACPI_PREDEFINED_INFO      ScopeNames[] = {
146     {{"_SB_",     0,      0}},
147     {{"_SI_",     0,      0}},
148     {{"_TZ_",     0,      0}},
149     {{{0,0,0,0},  0,      0}}   /* Table terminator */
150 };
151 
152 
153 /*******************************************************************************
154  *
155  * FUNCTION:    ApCheckForPredefinedMethod
156  *
157  * PARAMETERS:  Op              - A parse node of type "METHOD".
158  *              MethodInfo      - Saved info about this method
159  *
160  * RETURN:      None
161  *
162  * DESCRIPTION: If method is a predefined name, check that the number of
163  *              arguments and the return type (returns a value or not)
164  *              is correct.
165  *
166  ******************************************************************************/
167 
168 BOOLEAN
169 ApCheckForPredefinedMethod (
170     ACPI_PARSE_OBJECT       *Op,
171     ASL_METHOD_INFO         *MethodInfo)
172 {
173     UINT32                  Index;
174     UINT32                  RequiredArgsCurrent;
175     UINT32                  RequiredArgsOld;
176 
177 
178     /* Check for a match against the predefined name list */
179 
180     Index = ApCheckForPredefinedName (Op, Op->Asl.NameSeg);
181 
182     switch (Index)
183     {
184     case ACPI_NOT_RESERVED_NAME:        /* No underscore or _Txx or _xxx name not matched */
185     case ACPI_PREDEFINED_NAME:          /* Resource Name or reserved scope name */
186     case ACPI_COMPILER_RESERVED_NAME:   /* A _Txx that was not emitted by compiler */
187 
188         /* Just return, nothing to do */
189         return (FALSE);
190 
191 
192     case ACPI_EVENT_RESERVED_NAME:      /* _Lxx/_Exx/_Wxx/_Qxx methods */
193 
194         Gbl_ReservedMethods++;
195 
196         /* NumArguments must be zero for all _Lxx/_Exx/_Wxx/_Qxx methods */
197 
198         if (MethodInfo->NumArguments != 0)
199         {
200             sprintf (MsgBuffer, "%s requires %u", Op->Asl.ExternalName, 0);
201 
202             AslError (ASL_WARNING, ASL_MSG_RESERVED_ARG_COUNT_HI, Op,
203                 MsgBuffer);
204         }
205         break;
206 
207 
208     default:
209         /*
210          * Matched a predefined method name
211          *
212          * Validate the ASL-defined argument count. Allow two different legal
213          * arg counts.
214          */
215         Gbl_ReservedMethods++;
216 
217         RequiredArgsCurrent = PredefinedNames[Index].Info.ParamCount & 0x0F;
218         RequiredArgsOld = PredefinedNames[Index].Info.ParamCount >> 4;
219 
220         if ((MethodInfo->NumArguments != RequiredArgsCurrent) &&
221             (MethodInfo->NumArguments != RequiredArgsOld))
222         {
223             sprintf (MsgBuffer, "%4.4s requires %u",
224                 PredefinedNames[Index].Info.Name, RequiredArgsCurrent);
225 
226             if (MethodInfo->NumArguments > RequiredArgsCurrent)
227             {
228                 AslError (ASL_WARNING, ASL_MSG_RESERVED_ARG_COUNT_HI, Op,
229                     MsgBuffer);
230             }
231             else
232             {
233                 AslError (ASL_WARNING, ASL_MSG_RESERVED_ARG_COUNT_LO, Op,
234                     MsgBuffer);
235             }
236         }
237 
238         /*
239          * Check if method returns no value, but the predefined name is
240          * required to return a value
241          */
242         if (MethodInfo->NumReturnNoValue &&
243             PredefinedNames[Index].Info.ExpectedBtypes)
244         {
245             ApGetExpectedTypes (StringBuffer,
246                 PredefinedNames[Index].Info.ExpectedBtypes);
247 
248             sprintf (MsgBuffer, "%s required for %4.4s",
249                 StringBuffer, PredefinedNames[Index].Info.Name);
250 
251             AslError (ASL_WARNING, ASL_MSG_RESERVED_RETURN_VALUE, Op,
252                 MsgBuffer);
253         }
254         break;
255     }
256 
257     return (TRUE);
258 }
259 
260 
261 /*******************************************************************************
262  *
263  * FUNCTION:    ApCheckForUnexpectedReturnValue
264  *
265  * PARAMETERS:  Op              - A parse node of type "RETURN".
266  *              MethodInfo      - Saved info about this method
267  *
268  * RETURN:      None
269  *
270  * DESCRIPTION: Check for an unexpected return value from a predefined method.
271  *              Invoked for predefined methods that are defined to not return
272  *              any value. If there is a return value, issue a remark, since
273  *              the ASL writer may be confused as to the method definition
274  *              and/or functionality.
275  *
276  * Note: We ignore all return values of "Zero", since this is what a standalone
277  *       Return() statement will always generate -- so we ignore it here --
278  *       i.e., there is no difference between Return() and Return(Zero).
279  *       Also, a null Return() will be disassembled to return(Zero) -- so, we
280  *       don't want to generate extraneous remarks/warnings for a disassembled
281  *       ASL file.
282  *
283  ******************************************************************************/
284 
285 static void
286 ApCheckForUnexpectedReturnValue (
287     ACPI_PARSE_OBJECT       *Op,
288     ASL_METHOD_INFO         *MethodInfo)
289 {
290     ACPI_PARSE_OBJECT       *ReturnValueOp;
291 
292 
293     /* Ignore Return() and Return(Zero) (they are the same) */
294 
295     ReturnValueOp = Op->Asl.Child;
296     if (ReturnValueOp->Asl.ParseOpcode == PARSEOP_ZERO)
297     {
298         return;
299     }
300 
301     /* We have a valid return value, but the reserved name did not expect it */
302 
303     AslError (ASL_WARNING, ASL_MSG_RESERVED_NO_RETURN_VAL,
304         Op, MethodInfo->Op->Asl.ExternalName);
305 }
306 
307 
308 /*******************************************************************************
309  *
310  * FUNCTION:    ApCheckPredefinedReturnValue
311  *
312  * PARAMETERS:  Op              - A parse node of type "RETURN".
313  *              MethodInfo      - Saved info about this method
314  *
315  * RETURN:      None
316  *
317  * DESCRIPTION: If method is a predefined name, attempt to validate the return
318  *              value. Only "static" types can be validated - a simple return
319  *              of an integer/string/buffer/package or a named reference to
320  *              a static object. Values such as a Localx or Argx or a control
321  *              method invocation are not checked. Issue a warning if there is
322  *              a valid return value, but the reserved method defines no
323  *              return value.
324  *
325  ******************************************************************************/
326 
327 void
328 ApCheckPredefinedReturnValue (
329     ACPI_PARSE_OBJECT       *Op,
330     ASL_METHOD_INFO         *MethodInfo)
331 {
332     UINT32                  Index;
333     ACPI_PARSE_OBJECT       *ReturnValueOp;
334 
335 
336     /* Check parent method for a match against the predefined name list */
337 
338     Index = ApCheckForPredefinedName (MethodInfo->Op,
339                 MethodInfo->Op->Asl.NameSeg);
340 
341     switch (Index)
342     {
343     case ACPI_EVENT_RESERVED_NAME:      /* _Lxx/_Exx/_Wxx/_Qxx methods */
344 
345         /* No return value expected, warn if there is one */
346 
347         ApCheckForUnexpectedReturnValue (Op, MethodInfo);
348         return;
349 
350     case ACPI_NOT_RESERVED_NAME:        /* No underscore or _Txx or _xxx name not matched */
351     case ACPI_PREDEFINED_NAME:          /* Resource Name or reserved scope name */
352     case ACPI_COMPILER_RESERVED_NAME:   /* A _Txx that was not emitted by compiler */
353 
354         /* Just return, nothing to do */
355         return;
356 
357     default: /* A standard predefined ACPI name */
358 
359         if (!PredefinedNames[Index].Info.ExpectedBtypes)
360         {
361             /* No return value expected, warn if there is one */
362 
363             ApCheckForUnexpectedReturnValue (Op, MethodInfo);
364             return;
365         }
366 
367         /* Get the object returned, it is the next argument */
368 
369         ReturnValueOp = Op->Asl.Child;
370         switch (ReturnValueOp->Asl.ParseOpcode)
371         {
372         case PARSEOP_ZERO:
373         case PARSEOP_ONE:
374         case PARSEOP_ONES:
375         case PARSEOP_INTEGER:
376         case PARSEOP_STRING_LITERAL:
377         case PARSEOP_BUFFER:
378         case PARSEOP_PACKAGE:
379 
380             /* Static data return object - check against expected type */
381 
382             ApCheckObjectType (PredefinedNames[Index].Info.Name,
383                 ReturnValueOp,
384                 PredefinedNames[Index].Info.ExpectedBtypes,
385                 ACPI_NOT_PACKAGE_ELEMENT);
386 
387             /* For packages, check the individual package elements */
388 
389             if (ReturnValueOp->Asl.ParseOpcode == PARSEOP_PACKAGE)
390             {
391                 ApCheckPackage (ReturnValueOp, &PredefinedNames[Index]);
392             }
393             break;
394 
395         default:
396 
397             /*
398              * All other ops are very difficult or impossible to typecheck at
399              * compile time. These include all Localx, Argx, and method
400              * invocations. Also, NAMESEG and NAMESTRING because the type of
401              * any named object can be changed at runtime (for example,
402              * CopyObject will change the type of the target object.)
403              */
404             break;
405         }
406     }
407 }
408 
409 
410 /*******************************************************************************
411  *
412  * FUNCTION:    ApCheckForPredefinedObject
413  *
414  * PARAMETERS:  Op              - A parse node
415  *              Name            - The ACPI name to be checked
416  *
417  * RETURN:      None
418  *
419  * DESCRIPTION: Check for a predefined name for a static object (created via
420  *              the ASL Name operator). If it is a predefined ACPI name, ensure
421  *              that the name does not require any arguments (which would
422  *              require a control method implemenation of the name), and that
423  *              the type of the object is one of the expected types for the
424  *              predefined name.
425  *
426  ******************************************************************************/
427 
428 void
429 ApCheckForPredefinedObject (
430     ACPI_PARSE_OBJECT       *Op,
431     char                    *Name)
432 {
433     UINT32                  Index;
434     ACPI_PARSE_OBJECT       *ObjectOp;
435 
436 
437     /*
438      * Check for a real predefined name -- not a resource descriptor name
439      * or a predefined scope name
440      */
441     Index = ApCheckForPredefinedName (Op, Name);
442 
443     switch (Index)
444     {
445     case ACPI_NOT_RESERVED_NAME:        /* No underscore or _Txx or _xxx name not matched */
446     case ACPI_PREDEFINED_NAME:          /* Resource Name or reserved scope name */
447     case ACPI_COMPILER_RESERVED_NAME:   /* A _Txx that was not emitted by compiler */
448 
449         /* Nothing to do */
450         return;
451 
452     case ACPI_EVENT_RESERVED_NAME:      /* _Lxx/_Exx/_Wxx/_Qxx methods */
453 
454         /*
455          * These names must be control methods, by definition in ACPI spec.
456          * Also because they are defined to return no value. None of them
457          * require any arguments.
458          */
459         AslError (ASL_ERROR, ASL_MSG_RESERVED_METHOD, Op,
460             "with zero arguments");
461         return;
462 
463     default:
464         break;
465     }
466 
467     /* A standard predefined ACPI name */
468 
469     /*
470      * If this predefined name requires input arguments, then
471      * it must be implemented as a control method
472      */
473     if (PredefinedNames[Index].Info.ParamCount > 0)
474     {
475         AslError (ASL_ERROR, ASL_MSG_RESERVED_METHOD, Op,
476             "with arguments");
477         return;
478     }
479 
480     /*
481      * If no return value is expected from this predefined name, then
482      * it follows that it must be implemented as a control method
483      * (with zero args, because the args > 0 case was handled above)
484      * Examples are: _DIS, _INI, _IRC, _OFF, _ON, _PSx
485      */
486     if (!PredefinedNames[Index].Info.ExpectedBtypes)
487     {
488         AslError (ASL_ERROR, ASL_MSG_RESERVED_METHOD, Op,
489             "with zero arguments");
490         return;
491     }
492 
493     /* Typecheck the actual object, it is the next argument */
494 
495     ObjectOp = Op->Asl.Child->Asl.Next;
496     ApCheckObjectType (PredefinedNames[Index].Info.Name,
497         Op->Asl.Child->Asl.Next,
498         PredefinedNames[Index].Info.ExpectedBtypes,
499         ACPI_NOT_PACKAGE_ELEMENT);
500 
501     /* For packages, check the individual package elements */
502 
503     if (ObjectOp->Asl.ParseOpcode == PARSEOP_PACKAGE)
504     {
505         ApCheckPackage (ObjectOp, &PredefinedNames[Index]);
506     }
507 }
508 
509 
510 /*******************************************************************************
511  *
512  * FUNCTION:    ApCheckForPredefinedName
513  *
514  * PARAMETERS:  Op              - A parse node
515  *              Name            - NameSeg to check
516  *
517  * RETURN:      None
518  *
519  * DESCRIPTION: Check a NameSeg against the reserved list.
520  *
521  ******************************************************************************/
522 
523 UINT32
524 ApCheckForPredefinedName (
525     ACPI_PARSE_OBJECT       *Op,
526     char                    *Name)
527 {
528     UINT32                  i;
529 
530 
531     if (Name[0] == 0)
532     {
533         AcpiOsPrintf ("Found a null name, external = %s\n",
534             Op->Asl.ExternalName);
535     }
536 
537     /* All reserved names are prefixed with a single underscore */
538 
539     if (Name[0] != '_')
540     {
541         return (ACPI_NOT_RESERVED_NAME);
542     }
543 
544     /* Check for a standard predefined method name */
545 
546     for (i = 0; PredefinedNames[i].Info.Name[0]; i++)
547     {
548         if (ACPI_COMPARE_NAME (Name, PredefinedNames[i].Info.Name))
549         {
550             /* Return index into predefined array */
551             return (i);
552         }
553     }
554 
555     /* Check for resource names and predefined scope names */
556 
557     for (i = 0; ResourceNames[i].Info.Name[0]; i++)
558     {
559         if (ACPI_COMPARE_NAME (Name, ResourceNames[i].Info.Name))
560         {
561             return (ACPI_PREDEFINED_NAME);
562         }
563     }
564 
565     for (i = 0; ScopeNames[i].Info.Name[0]; i++)
566     {
567         if (ACPI_COMPARE_NAME (Name, ScopeNames[i].Info.Name))
568         {
569             return (ACPI_PREDEFINED_NAME);
570         }
571     }
572 
573     /* Check for _Lxx/_Exx/_Wxx/_Qxx/_T_x. Warning if unknown predefined name */
574 
575     return (ApCheckForSpecialName (Op, Name));
576 }
577 
578 
579 /*******************************************************************************
580  *
581  * FUNCTION:    ApCheckForSpecialName
582  *
583  * PARAMETERS:  Op              - A parse node
584  *              Name            - NameSeg to check
585  *
586  * RETURN:      None
587  *
588  * DESCRIPTION: Check for the "special" predefined names -
589  *              _Lxx, _Exx, _Qxx, _Wxx, and _T_x
590  *
591  ******************************************************************************/
592 
593 static UINT32
594 ApCheckForSpecialName (
595     ACPI_PARSE_OBJECT       *Op,
596     char                    *Name)
597 {
598 
599     /*
600      * Check for the "special" predefined names. We already know that the
601      * first character is an underscore.
602      *   GPE:  _Lxx
603      *   GPE:  _Exx
604      *   GPE:  _Wxx
605      *   EC:   _Qxx
606      */
607     if ((Name[1] == 'L') ||
608         (Name[1] == 'E') ||
609         (Name[1] == 'W') ||
610         (Name[1] == 'Q'))
611     {
612         /* The next two characters must be hex digits */
613 
614         if ((isxdigit ((int) Name[2])) &&
615             (isxdigit ((int) Name[3])))
616         {
617             return (ACPI_EVENT_RESERVED_NAME);
618         }
619     }
620 
621     /* Check for the names reserved for the compiler itself: _T_x */
622 
623     else if ((Op->Asl.ExternalName[1] == 'T') &&
624              (Op->Asl.ExternalName[2] == '_'))
625     {
626         /* Ignore if actually emitted by the compiler */
627 
628         if (Op->Asl.CompileFlags & NODE_COMPILER_EMITTED)
629         {
630             return (ACPI_NOT_RESERVED_NAME);
631         }
632 
633         /*
634          * Was not actually emitted by the compiler. This is a special case,
635          * however. If the ASL code being compiled was the result of a
636          * dissasembly, it may possibly contain valid compiler-emitted names
637          * of the form "_T_x". We don't want to issue an error or even a
638          * warning and force the user to manually change the names. So, we
639          * will issue a remark instead.
640          */
641         AslError (ASL_REMARK, ASL_MSG_COMPILER_RESERVED, Op, Op->Asl.ExternalName);
642         return (ACPI_COMPILER_RESERVED_NAME);
643     }
644 
645     /*
646      * The name didn't match any of the known predefined names. Flag it as a
647      * warning, since the entire namespace starting with an underscore is
648      * reserved by the ACPI spec.
649      */
650     AslError (ASL_WARNING, ASL_MSG_UNKNOWN_RESERVED_NAME, Op,
651         Op->Asl.ExternalName);
652 
653     return (ACPI_NOT_RESERVED_NAME);
654 }
655 
656 
657 /*******************************************************************************
658  *
659  * FUNCTION:    ApCheckObjectType
660  *
661  * PARAMETERS:  PredefinedName  - Name of the predefined object we are checking
662  *              Op              - Current parse node
663  *              ExpectedBtypes  - Bitmap of expected return type(s)
664  *              PackageIndex    - Index of object within parent package (if
665  *                                applicable - ACPI_NOT_PACKAGE_ELEMENT
666  *                                otherwise)
667  *
668  * RETURN:      None
669  *
670  * DESCRIPTION: Check if the object type is one of the types that is expected
671  *              by the predefined name. Only a limited number of object types
672  *              can be returned by the predefined names.
673  *
674  ******************************************************************************/
675 
676 ACPI_STATUS
677 ApCheckObjectType (
678     const char              *PredefinedName,
679     ACPI_PARSE_OBJECT       *Op,
680     UINT32                  ExpectedBtypes,
681     UINT32                  PackageIndex)
682 {
683     UINT32                  ReturnBtype;
684     char                    *TypeName;
685 
686 
687     if (!Op)
688     {
689         return (AE_TYPE);
690     }
691 
692     /* Map the parse opcode to a bitmapped return type (RTYPE) */
693 
694     switch (Op->Asl.ParseOpcode)
695     {
696     case PARSEOP_ZERO:
697     case PARSEOP_ONE:
698     case PARSEOP_ONES:
699     case PARSEOP_INTEGER:
700         ReturnBtype = ACPI_RTYPE_INTEGER;
701         TypeName = "Integer";
702         break;
703 
704     case PARSEOP_STRING_LITERAL:
705         ReturnBtype = ACPI_RTYPE_STRING;
706         TypeName = "String";
707         break;
708 
709     case PARSEOP_BUFFER:
710         ReturnBtype = ACPI_RTYPE_BUFFER;
711         TypeName = "Buffer";
712         break;
713 
714     case PARSEOP_PACKAGE:
715     case PARSEOP_VAR_PACKAGE:
716         ReturnBtype = ACPI_RTYPE_PACKAGE;
717         TypeName = "Package";
718         break;
719 
720     case PARSEOP_NAMESEG:
721     case PARSEOP_NAMESTRING:
722         ReturnBtype = ACPI_RTYPE_REFERENCE;
723         TypeName = "Reference";
724         break;
725 
726     default:
727         /* Not one of the supported object types */
728 
729         TypeName = UtGetOpName (Op->Asl.ParseOpcode);
730         goto TypeErrorExit;
731     }
732 
733     /* Exit if the object is one of the expected types */
734 
735     if (ReturnBtype & ExpectedBtypes)
736     {
737         return (AE_OK);
738     }
739 
740 
741 TypeErrorExit:
742 
743     /* Format the expected types and emit an error message */
744 
745     ApGetExpectedTypes (StringBuffer, ExpectedBtypes);
746 
747     if (PackageIndex == ACPI_NOT_PACKAGE_ELEMENT)
748     {
749         sprintf (MsgBuffer, "%s: found %s, %s required",
750             PredefinedName, TypeName, StringBuffer);
751     }
752     else
753     {
754         sprintf (MsgBuffer, "%s: found %s at index %u, %s required",
755             PredefinedName, TypeName, PackageIndex, StringBuffer);
756     }
757 
758     AslError (ASL_ERROR, ASL_MSG_RESERVED_OPERAND_TYPE, Op, MsgBuffer);
759     return (AE_TYPE);
760 }
761 
762 
763 /*******************************************************************************
764  *
765  * FUNCTION:    ApDisplayReservedNames
766  *
767  * PARAMETERS:  None
768  *
769  * RETURN:      None
770  *
771  * DESCRIPTION: Dump information about the ACPI predefined names and predefined
772  *              resource descriptor names.
773  *
774  ******************************************************************************/
775 
776 void
777 ApDisplayReservedNames (
778     void)
779 {
780     const ACPI_PREDEFINED_INFO  *ThisName;
781     char                        TypeBuffer[48]; /* Room for 5 types */
782     UINT32                      Count;
783 
784 
785     /*
786      * Predefined names/methods
787      */
788     printf ("\nPredefined Name Information\n\n");
789 
790     Count = 0;
791     ThisName = PredefinedNames;
792     while (ThisName->Info.Name[0])
793     {
794         printf ("%4.4s    Requires %u arguments, ",
795             ThisName->Info.Name, ThisName->Info.ParamCount & 0x0F);
796 
797         if (ThisName->Info.ExpectedBtypes)
798         {
799             ApGetExpectedTypes (TypeBuffer, ThisName->Info.ExpectedBtypes);
800             printf ("Must return: %s\n", TypeBuffer);
801         }
802         else
803         {
804             printf ("No return value\n");
805         }
806 
807         /*
808          * Skip next entry in the table if this name returns a Package
809          * (next entry contains the package info)
810          */
811         if (ThisName->Info.ExpectedBtypes & ACPI_RTYPE_PACKAGE)
812         {
813             ThisName++;
814         }
815 
816         Count++;
817         ThisName++;
818     }
819 
820     printf ("%u Predefined Names are recognized\n", Count);
821 
822     /*
823      * Resource Descriptor names
824      */
825     printf ("\nResource Descriptor Predefined Names\n\n");
826 
827     Count = 0;
828     ThisName = ResourceNames;
829     while (ThisName->Info.Name[0])
830     {
831         printf ("%4.4s    Resource Descriptor\n", ThisName->Info.Name);
832         Count++;
833         ThisName++;
834     }
835 
836     printf ("%u Resource Descriptor Names are recognized\n", Count);
837 
838     /*
839      * Predefined scope names
840      */
841     printf ("\nPredefined Scope Names\n\n");
842 
843     ThisName = ScopeNames;
844     while (ThisName->Info.Name[0])
845     {
846         printf ("%4.4s    Scope\n", ThisName->Info.Name);
847         ThisName++;
848     }
849 }
850 
851 
852 /*******************************************************************************
853  *
854  * FUNCTION:    ApGetExpectedTypes
855  *
856  * PARAMETERS:  Buffer              - Where the formatted string is returned
857  *              ExpectedBTypes      - Bitfield of expected data types
858  *
859  * RETURN:      None, formatted string
860  *
861  * DESCRIPTION: Format the expected object types into a printable string.
862  *
863  ******************************************************************************/
864 
865 static void
866 ApGetExpectedTypes (
867     char                        *Buffer,
868     UINT32                      ExpectedBtypes)
869 {
870     UINT32                      ThisRtype;
871     UINT32                      i;
872     UINT32                      j;
873 
874 
875     j = 1;
876     Buffer[0] = 0;
877     ThisRtype = ACPI_RTYPE_INTEGER;
878 
879     for (i = 0; i < ACPI_NUM_RTYPES; i++)
880     {
881         /* If one of the expected types, concatenate the name of this type */
882 
883         if (ExpectedBtypes & ThisRtype)
884         {
885             ACPI_STRCAT (Buffer, &AcpiRtypeNames[i][j]);
886             j = 0;              /* Use name separator from now on */
887         }
888         ThisRtype <<= 1;    /* Next Rtype */
889     }
890 }
891