kernel: Sync ACPICA with Intel's version 20140114.
[dragonfly.git] / sys / contrib / dev / acpica / source / compiler / aslprepkg.c
1 /******************************************************************************
2  *
3  * Module Name: aslprepkg - support for ACPI predefined name package objects
4  *
5  *****************************************************************************/
6
7 /*
8  * Copyright (C) 2000 - 2014, 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 #include "aslcompiler.h"
45 #include "aslcompiler.y.h"
46 #include "acpredef.h"
47
48
49 #define _COMPONENT          ACPI_COMPILER
50         ACPI_MODULE_NAME    ("aslprepkg")
51
52
53 /* Local prototypes */
54
55 static void
56 ApCheckPackageElements (
57     const char                  *PredefinedName,
58     ACPI_PARSE_OBJECT           *Op,
59     UINT8                       Type1,
60     UINT32                      Count1,
61     UINT8                       Type2,
62     UINT32                      Count2);
63
64 static void
65 ApCheckPackageList (
66     const char                  *PredefinedName,
67     ACPI_PARSE_OBJECT           *ParentOp,
68     const ACPI_PREDEFINED_INFO  *Package,
69     UINT32                      StartIndex,
70     UINT32                      Count);
71
72 static void
73 ApPackageTooSmall (
74     const char                  *PredefinedName,
75     ACPI_PARSE_OBJECT           *Op,
76     UINT32                      Count,
77     UINT32                      ExpectedCount);
78
79 static void
80 ApZeroLengthPackage (
81     const char                  *PredefinedName,
82     ACPI_PARSE_OBJECT           *Op);
83
84 static void
85 ApPackageTooLarge (
86     const char                  *PredefinedName,
87     ACPI_PARSE_OBJECT           *Op,
88     UINT32                      Count,
89     UINT32                      ExpectedCount);
90
91
92 /*******************************************************************************
93  *
94  * FUNCTION:    ApCheckPackage
95  *
96  * PARAMETERS:  ParentOp            - Parser op for the package
97  *              Predefined          - Pointer to package-specific info for
98  *                                    the method
99  *
100  * RETURN:      None
101  *
102  * DESCRIPTION: Top-level validation for predefined name return package
103  *              objects.
104  *
105  ******************************************************************************/
106
107 void
108 ApCheckPackage (
109     ACPI_PARSE_OBJECT           *ParentOp,
110     const ACPI_PREDEFINED_INFO  *Predefined)
111 {
112     ACPI_PARSE_OBJECT           *Op;
113     const ACPI_PREDEFINED_INFO  *Package;
114     ACPI_STATUS                 Status;
115     UINT32                      ExpectedCount;
116     UINT32                      Count;
117     UINT32                      i;
118
119
120     /* The package info for this name is in the next table entry */
121
122     Package = Predefined + 1;
123
124     /* First child is the package length */
125
126     Op = ParentOp->Asl.Child;
127     Count = (UINT32) Op->Asl.Value.Integer;
128
129     /*
130      * Many of the variable-length top-level packages are allowed to simply
131      * have zero elements. This allows the BIOS to tell the host that even
132      * though the predefined name/method exists, the feature is not supported.
133      * Other package types require one or more elements. In any case, there
134      * is no need to continue validation.
135      */
136     if (!Count)
137     {
138         switch (Package->RetInfo.Type)
139         {
140         case ACPI_PTYPE1_FIXED:
141         case ACPI_PTYPE1_OPTION:
142         case ACPI_PTYPE2_PKG_COUNT:
143         case ACPI_PTYPE2_REV_FIXED:
144
145             ApZeroLengthPackage (Predefined->Info.Name, ParentOp);
146             break;
147
148         case ACPI_PTYPE1_VAR:
149         case ACPI_PTYPE2:
150         case ACPI_PTYPE2_COUNT:
151         case ACPI_PTYPE2_FIXED:
152         case ACPI_PTYPE2_MIN:
153         case ACPI_PTYPE2_FIX_VAR:
154         default:
155
156             break;
157         }
158
159         return;
160     }
161
162     /* Get the first element of the package */
163
164     Op = Op->Asl.Next;
165
166     /* Decode the package type */
167
168     switch (Package->RetInfo.Type)
169     {
170     case ACPI_PTYPE1_FIXED:
171         /*
172          * The package count is fixed and there are no sub-packages
173          *
174          * If package is too small, exit.
175          * If package is larger than expected, issue warning but continue
176          */
177         ExpectedCount = Package->RetInfo.Count1 + Package->RetInfo.Count2;
178         if (Count < ExpectedCount)
179         {
180             goto PackageTooSmall;
181         }
182         else if (Count > ExpectedCount)
183         {
184             ApPackageTooLarge (Predefined->Info.Name, ParentOp,
185                 Count, ExpectedCount);
186         }
187
188         /* Validate all elements of the package */
189
190         ApCheckPackageElements (Predefined->Info.Name, Op,
191             Package->RetInfo.ObjectType1, Package->RetInfo.Count1,
192             Package->RetInfo.ObjectType2, Package->RetInfo.Count2);
193         break;
194
195     case ACPI_PTYPE1_VAR:
196         /*
197          * The package count is variable, there are no sub-packages,
198          * and all elements must be of the same type
199          */
200         for (i = 0; i < Count; i++)
201         {
202             ApCheckObjectType (Predefined->Info.Name, Op,
203                 Package->RetInfo.ObjectType1, i);
204             Op = Op->Asl.Next;
205         }
206         break;
207
208     case ACPI_PTYPE1_OPTION:
209         /*
210          * The package count is variable, there are no sub-packages.
211          * There are a fixed number of required elements, and a variable
212          * number of optional elements.
213          *
214          * Check if package is at least as large as the minimum required
215          */
216         ExpectedCount = Package->RetInfo3.Count;
217         if (Count < ExpectedCount)
218         {
219             goto PackageTooSmall;
220         }
221
222         /* Variable number of sub-objects */
223
224         for (i = 0; i < Count; i++)
225         {
226             if (i < Package->RetInfo3.Count)
227             {
228                 /* These are the required package elements (0, 1, or 2) */
229
230                 ApCheckObjectType (Predefined->Info.Name, Op,
231                     Package->RetInfo3.ObjectType[i], i);
232             }
233             else
234             {
235                 /* These are the optional package elements */
236
237                 ApCheckObjectType (Predefined->Info.Name, Op,
238                     Package->RetInfo3.TailObjectType, i);
239             }
240             Op = Op->Asl.Next;
241         }
242         break;
243
244     case ACPI_PTYPE2_REV_FIXED:
245
246         /* First element is the (Integer) revision */
247
248         ApCheckObjectType (Predefined->Info.Name, Op,
249             ACPI_RTYPE_INTEGER, 0);
250
251         Op = Op->Asl.Next;
252         Count--;
253
254         /* Examine the sub-packages */
255
256         ApCheckPackageList (Predefined->Info.Name, Op,
257             Package, 1, Count);
258         break;
259
260     case ACPI_PTYPE2_PKG_COUNT:
261
262         /* First element is the (Integer) count of sub-packages to follow */
263
264         Status = ApCheckObjectType (Predefined->Info.Name, Op,
265             ACPI_RTYPE_INTEGER, 0);
266
267         /* We must have an integer count from above (otherwise, use Count) */
268
269         if (ACPI_SUCCESS (Status))
270         {
271             /*
272              * Count cannot be larger than the parent package length, but
273              * allow it to be smaller. The >= accounts for the Integer above.
274              */
275             ExpectedCount = (UINT32) Op->Asl.Value.Integer;
276             if (ExpectedCount >= Count)
277             {
278                 goto PackageTooSmall;
279             }
280
281             Count = ExpectedCount;
282         }
283
284         Op = Op->Asl.Next;
285
286         /* Examine the sub-packages */
287
288         ApCheckPackageList (Predefined->Info.Name, Op,
289             Package, 1, Count);
290         break;
291
292     case ACPI_PTYPE2:
293     case ACPI_PTYPE2_FIXED:
294     case ACPI_PTYPE2_MIN:
295     case ACPI_PTYPE2_COUNT:
296     case ACPI_PTYPE2_FIX_VAR:
297         /*
298          * These types all return a single Package that consists of a
299          * variable number of sub-Packages.
300          */
301
302         /* Examine the sub-packages */
303
304         ApCheckPackageList (Predefined->Info.Name, Op,
305             Package, 0, Count);
306         break;
307
308     default:
309         return;
310     }
311
312     return;
313
314 PackageTooSmall:
315     ApPackageTooSmall (Predefined->Info.Name, ParentOp,
316         Count, ExpectedCount);
317 }
318
319
320 /*******************************************************************************
321  *
322  * FUNCTION:    ApCheckPackageElements
323  *
324  * PARAMETERS:  PredefinedName      - Name of the predefined object
325  *              Op                  - Parser op for the package
326  *              Type1               - Object type for first group
327  *              Count1              - Count for first group
328  *              Type2               - Object type for second group
329  *              Count2              - Count for second group
330  *
331  * RETURN:      None
332  *
333  * DESCRIPTION: Validate all elements of a package. Works with packages that
334  *              are defined to contain up to two groups of different object
335  *              types.
336  *
337  ******************************************************************************/
338
339 static void
340 ApCheckPackageElements (
341     const char              *PredefinedName,
342     ACPI_PARSE_OBJECT       *Op,
343     UINT8                   Type1,
344     UINT32                  Count1,
345     UINT8                   Type2,
346     UINT32                  Count2)
347 {
348     UINT32                  i;
349
350
351     /*
352      * Up to two groups of package elements are supported by the data
353      * structure. All elements in each group must be of the same type.
354      * The second group can have a count of zero.
355      *
356      * Aborts check upon a NULL package element, as this means (at compile
357      * time) that the remainder of the package elements are also NULL
358      * (This is the only way to create NULL package elements.)
359      */
360     for (i = 0; (i < Count1) && Op; i++)
361     {
362         ApCheckObjectType (PredefinedName, Op, Type1, i);
363         Op = Op->Asl.Next;
364     }
365
366     for (i = 0; (i < Count2) && Op; i++)
367     {
368         ApCheckObjectType (PredefinedName, Op, Type2, (i + Count1));
369         Op = Op->Asl.Next;
370     }
371 }
372
373
374 /*******************************************************************************
375  *
376  * FUNCTION:    ApCheckPackageList
377  *
378  * PARAMETERS:  PredefinedName      - Name of the predefined object
379  *              ParentOp            - Parser op of the parent package
380  *              Package             - Package info for this predefined name
381  *              StartIndex          - Index in parent package where list begins
382  *              ParentCount         - Element count of parent package
383  *
384  * RETURN:      None
385  *
386  * DESCRIPTION: Validate the individual package elements for a predefined name.
387  *              Handles the cases where the predefined name is defined as a
388  *              Package of Packages (subpackages). These are the types:
389  *
390  *              ACPI_PTYPE2
391  *              ACPI_PTYPE2_FIXED
392  *              ACPI_PTYPE2_MIN
393  *              ACPI_PTYPE2_COUNT
394  *              ACPI_PTYPE2_FIX_VAR
395  *
396  ******************************************************************************/
397
398 static void
399 ApCheckPackageList (
400     const char                  *PredefinedName,
401     ACPI_PARSE_OBJECT           *ParentOp,
402     const ACPI_PREDEFINED_INFO  *Package,
403     UINT32                      StartIndex,
404     UINT32                      ParentCount)
405 {
406     ACPI_PARSE_OBJECT           *SubPackageOp = ParentOp;
407     ACPI_PARSE_OBJECT           *Op;
408     ACPI_STATUS                 Status;
409     UINT32                      Count;
410     UINT32                      ExpectedCount;
411     UINT32                      i;
412     UINT32                      j;
413
414
415     /*
416      * Validate each subpackage in the parent Package
417      *
418      * Note: We ignore NULL package elements on the assumption that
419      * they will be initialized by the BIOS or other ASL code.
420      */
421     for (i = 0; (i < ParentCount) && SubPackageOp; i++)
422     {
423         /* Each object in the list must be of type Package */
424
425         Status = ApCheckObjectType (PredefinedName, SubPackageOp,
426             ACPI_RTYPE_PACKAGE, i + StartIndex);
427         if (ACPI_FAILURE (Status))
428         {
429             goto NextSubpackage;
430         }
431
432         /* Examine the different types of expected subpackages */
433
434         Op = SubPackageOp->Asl.Child;
435
436         /* First child is the package length */
437
438         Count = (UINT32) Op->Asl.Value.Integer;
439         Op = Op->Asl.Next;
440
441         /* The subpackage must have at least one element */
442
443         if (!Count)
444         {
445             ApZeroLengthPackage (PredefinedName, SubPackageOp);
446             goto NextSubpackage;
447         }
448
449         /*
450          * Decode the package type.
451          * PTYPE2 indicates that a "package of packages" is expected for
452          * this name. The various flavors of PTYPE2 indicate the number
453          * and format of the subpackages.
454          */
455         switch (Package->RetInfo.Type)
456         {
457         case ACPI_PTYPE2:
458         case ACPI_PTYPE2_PKG_COUNT:
459         case ACPI_PTYPE2_REV_FIXED:
460
461             /* Each subpackage has a fixed number of elements */
462
463             ExpectedCount = Package->RetInfo.Count1 + Package->RetInfo.Count2;
464             if (Count < ExpectedCount)
465             {
466                 ApPackageTooSmall (PredefinedName, SubPackageOp,
467                     Count, ExpectedCount);
468                 break;
469             }
470
471             ApCheckPackageElements (PredefinedName, Op,
472                 Package->RetInfo.ObjectType1, Package->RetInfo.Count1,
473                 Package->RetInfo.ObjectType2, Package->RetInfo.Count2);
474             break;
475
476         case ACPI_PTYPE2_FIX_VAR:
477             /*
478              * Each subpackage has a fixed number of elements and an
479              * optional element
480              */
481             ExpectedCount = Package->RetInfo.Count1 + Package->RetInfo.Count2;
482             if (Count < ExpectedCount)
483             {
484                 ApPackageTooSmall (PredefinedName, SubPackageOp,
485                     Count, ExpectedCount);
486                 break;
487             }
488
489             ApCheckPackageElements (PredefinedName, Op,
490                 Package->RetInfo.ObjectType1, Package->RetInfo.Count1,
491                 Package->RetInfo.ObjectType2,
492                 Count - Package->RetInfo.Count1);
493             break;
494
495         case ACPI_PTYPE2_FIXED:
496
497             /* Each sub-package has a fixed length */
498
499             ExpectedCount = Package->RetInfo2.Count;
500             if (Count < ExpectedCount)
501             {
502                 ApPackageTooSmall (PredefinedName, SubPackageOp,
503                     Count, ExpectedCount);
504                 break;
505             }
506
507             /* Check each object/type combination */
508
509             for (j = 0; j < ExpectedCount; j++)
510             {
511                 ApCheckObjectType (PredefinedName, Op,
512                     Package->RetInfo2.ObjectType[j], j);
513
514                 Op = Op->Asl.Next;
515             }
516             break;
517
518         case ACPI_PTYPE2_MIN:
519
520             /* Each sub-package has a variable but minimum length */
521
522             ExpectedCount = Package->RetInfo.Count1;
523             if (Count < ExpectedCount)
524             {
525                 ApPackageTooSmall (PredefinedName, SubPackageOp,
526                     Count, ExpectedCount);
527                 break;
528             }
529
530             /* Check the type of each sub-package element */
531
532             ApCheckPackageElements (PredefinedName, Op,
533                 Package->RetInfo.ObjectType1, Count, 0, 0);
534             break;
535
536         case ACPI_PTYPE2_COUNT:
537             /*
538              * First element is the (Integer) count of elements, including
539              * the count field (the ACPI name is NumElements)
540              */
541             Status = ApCheckObjectType (PredefinedName, Op,
542                 ACPI_RTYPE_INTEGER, 0);
543
544             /* We must have an integer count from above (otherwise, use Count) */
545
546             if (ACPI_SUCCESS (Status))
547             {
548                 /*
549                  * Make sure package is large enough for the Count and is
550                  * is as large as the minimum size
551                  */
552                 ExpectedCount = (UINT32) Op->Asl.Value.Integer;
553
554                 if (Count < ExpectedCount)
555                 {
556                     ApPackageTooSmall (PredefinedName, SubPackageOp,
557                         Count, ExpectedCount);
558                     break;
559                 }
560                 else if (Count > ExpectedCount)
561                 {
562                     ApPackageTooLarge (PredefinedName, SubPackageOp,
563                         Count, ExpectedCount);
564                 }
565
566                 /* Some names of this type have a minimum length */
567
568                 if (Count < Package->RetInfo.Count1)
569                 {
570                     ExpectedCount = Package->RetInfo.Count1;
571                     ApPackageTooSmall (PredefinedName, SubPackageOp,
572                         Count, ExpectedCount);
573                     break;
574                 }
575
576                 Count = ExpectedCount;
577             }
578
579             /* Check the type of each sub-package element */
580
581             Op = Op->Asl.Next;
582             ApCheckPackageElements (PredefinedName, Op,
583                 Package->RetInfo.ObjectType1, (Count - 1), 0, 0);
584             break;
585
586         default:
587             break;
588         }
589
590 NextSubpackage:
591         SubPackageOp = SubPackageOp->Asl.Next;
592     }
593 }
594
595
596 /*******************************************************************************
597  *
598  * FUNCTION:    ApPackageTooSmall
599  *
600  * PARAMETERS:  PredefinedName      - Name of the predefined object
601  *              Op                  - Current parser op
602  *              Count               - Actual package element count
603  *              ExpectedCount       - Expected package element count
604  *
605  * RETURN:      None
606  *
607  * DESCRIPTION: Issue error message for a package that is smaller than
608  *              required.
609  *
610  ******************************************************************************/
611
612 static void
613 ApPackageTooSmall (
614     const char                  *PredefinedName,
615     ACPI_PARSE_OBJECT           *Op,
616     UINT32                      Count,
617     UINT32                      ExpectedCount)
618 {
619
620     sprintf (MsgBuffer, "%s: length %u, required minimum is %u",
621         PredefinedName, Count, ExpectedCount);
622
623     AslError (ASL_ERROR, ASL_MSG_RESERVED_PACKAGE_LENGTH, Op, MsgBuffer);
624 }
625
626
627 /*******************************************************************************
628  *
629  * FUNCTION:    ApZeroLengthPackage
630  *
631  * PARAMETERS:  PredefinedName      - Name of the predefined object
632  *              Op                  - Current parser op
633  *
634  * RETURN:      None
635  *
636  * DESCRIPTION: Issue error message for a zero-length package (a package that
637  *              is required to have a non-zero length). Variable length
638  *              packages seem to be allowed to have zero length, however.
639  *              Even if not allowed, BIOS code does it.
640  *
641  ******************************************************************************/
642
643 static void
644 ApZeroLengthPackage (
645     const char                  *PredefinedName,
646     ACPI_PARSE_OBJECT           *Op)
647 {
648
649     sprintf (MsgBuffer, "%s: length is zero", PredefinedName);
650
651     AslError (ASL_ERROR, ASL_MSG_RESERVED_PACKAGE_LENGTH, Op, MsgBuffer);
652 }
653
654
655 /*******************************************************************************
656  *
657  * FUNCTION:    ApPackageTooLarge
658  *
659  * PARAMETERS:  PredefinedName      - Name of the predefined object
660  *              Op                  - Current parser op
661  *              Count               - Actual package element count
662  *              ExpectedCount       - Expected package element count
663  *
664  * RETURN:      None
665  *
666  * DESCRIPTION: Issue a remark for a package that is larger than expected.
667  *
668  ******************************************************************************/
669
670 static void
671 ApPackageTooLarge (
672     const char                  *PredefinedName,
673     ACPI_PARSE_OBJECT           *Op,
674     UINT32                      Count,
675     UINT32                      ExpectedCount)
676 {
677
678     sprintf (MsgBuffer, "%s: length is %u, only %u required",
679         PredefinedName, Count, ExpectedCount);
680
681     AslError (ASL_REMARK, ASL_MSG_RESERVED_PACKAGE_LENGTH, Op, MsgBuffer);
682 }