xref: /illumos-gate/usr/src/cmd/acpi/iasl/aslprepkg.c (revision 35786f68)
1 /******************************************************************************
2  *
3  * Module Name: aslprepkg - support for ACPI predefined name package objects
4  *
5  *****************************************************************************/
6 
7 /******************************************************************************
8  *
9  * 1. Copyright Notice
10  *
11  * Some or all of this work - Copyright (c) 1999 - 2018, Intel Corp.
12  * All rights reserved.
13  *
14  * 2. License
15  *
16  * 2.1. This is your license from Intel Corp. under its intellectual property
17  * rights. You may have additional license terms from the party that provided
18  * you this software, covering your right to use that party's intellectual
19  * property rights.
20  *
21  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
22  * copy of the source code appearing in this file ("Covered Code") an
23  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
24  * base code distributed originally by Intel ("Original Intel Code") to copy,
25  * make derivatives, distribute, use and display any portion of the Covered
26  * Code in any form, with the right to sublicense such rights; and
27  *
28  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
29  * license (with the right to sublicense), under only those claims of Intel
30  * patents that are infringed by the Original Intel Code, to make, use, sell,
31  * offer to sell, and import the Covered Code and derivative works thereof
32  * solely to the minimum extent necessary to exercise the above copyright
33  * license, and in no event shall the patent license extend to any additions
34  * to or modifications of the Original Intel Code. No other license or right
35  * is granted directly or by implication, estoppel or otherwise;
36  *
37  * The above copyright and patent license is granted only if the following
38  * conditions are met:
39  *
40  * 3. Conditions
41  *
42  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
43  * Redistribution of source code of any substantial portion of the Covered
44  * Code or modification with rights to further distribute source must include
45  * the above Copyright Notice, the above License, this list of Conditions,
46  * and the following Disclaimer and Export Compliance provision. In addition,
47  * Licensee must cause all Covered Code to which Licensee contributes to
48  * contain a file documenting the changes Licensee made to create that Covered
49  * Code and the date of any change. Licensee must include in that file the
50  * documentation of any changes made by any predecessor Licensee. Licensee
51  * must include a prominent statement that the modification is derived,
52  * directly or indirectly, from Original Intel Code.
53  *
54  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
55  * Redistribution of source code of any substantial portion of the Covered
56  * Code or modification without rights to further distribute source must
57  * include the following Disclaimer and Export Compliance provision in the
58  * documentation and/or other materials provided with distribution. In
59  * addition, Licensee may not authorize further sublicense of source of any
60  * portion of the Covered Code, and must include terms to the effect that the
61  * license from Licensee to its licensee is limited to the intellectual
62  * property embodied in the software Licensee provides to its licensee, and
63  * not to intellectual property embodied in modifications its licensee may
64  * make.
65  *
66  * 3.3. Redistribution of Executable. Redistribution in executable form of any
67  * substantial portion of the Covered Code or modification must reproduce the
68  * above Copyright Notice, and the following Disclaimer and Export Compliance
69  * provision in the documentation and/or other materials provided with the
70  * distribution.
71  *
72  * 3.4. Intel retains all right, title, and interest in and to the Original
73  * Intel Code.
74  *
75  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
76  * Intel shall be used in advertising or otherwise to promote the sale, use or
77  * other dealings in products derived from or relating to the Covered Code
78  * without prior written authorization from Intel.
79  *
80  * 4. Disclaimer and Export Compliance
81  *
82  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
83  * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
84  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
85  * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
86  * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
87  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
88  * PARTICULAR PURPOSE.
89  *
90  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
91  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
92  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
93  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
94  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
95  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
96  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
97  * LIMITED REMEDY.
98  *
99  * 4.3. Licensee shall not export, either directly or indirectly, any of this
100  * software or system incorporating such software without first obtaining any
101  * required license or other approval from the U. S. Department of Commerce or
102  * any other agency or department of the United States Government. In the
103  * event Licensee exports any such software from the United States or
104  * re-exports any such software from a foreign destination, Licensee shall
105  * ensure that the distribution and export/re-export of the software is in
106  * compliance with all laws, regulations, orders, or other restrictions of the
107  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
108  * any of its subsidiaries will export/re-export any technical data, process,
109  * software, or service, directly or indirectly, to any country for which the
110  * United States government or any agency thereof requires an export license,
111  * other governmental approval, or letter of assurance, without first obtaining
112  * such license, approval or letter.
113  *
114  *****************************************************************************
115  *
116  * Alternatively, you may choose to be licensed under the terms of the
117  * following license:
118  *
119  * Redistribution and use in source and binary forms, with or without
120  * modification, are permitted provided that the following conditions
121  * are met:
122  * 1. Redistributions of source code must retain the above copyright
123  *    notice, this list of conditions, and the following disclaimer,
124  *    without modification.
125  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
126  *    substantially similar to the "NO WARRANTY" disclaimer below
127  *    ("Disclaimer") and any redistribution must be conditioned upon
128  *    including a substantially similar Disclaimer requirement for further
129  *    binary redistribution.
130  * 3. Neither the names of the above-listed copyright holders nor the names
131  *    of any contributors may be used to endorse or promote products derived
132  *    from this software without specific prior written permission.
133  *
134  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
135  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
136  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
137  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
138  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
139  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
140  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
141  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
142  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
143  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
144  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
145  *
146  * Alternatively, you may choose to be licensed under the terms of the
147  * GNU General Public License ("GPL") version 2 as published by the Free
148  * Software Foundation.
149  *
150  *****************************************************************************/
151 
152 #include "aslcompiler.h"
153 #include "aslcompiler.y.h"
154 #include "acpredef.h"
155 
156 
157 #define _COMPONENT          ACPI_COMPILER
158         ACPI_MODULE_NAME    ("aslprepkg")
159 
160 
161 /* Local prototypes */
162 
163 static ACPI_PARSE_OBJECT *
164 ApCheckPackageElements (
165     const char                  *PredefinedName,
166     ACPI_PARSE_OBJECT           *Op,
167     UINT8                       Type1,
168     UINT32                      Count1,
169     UINT8                       Type2,
170     UINT32                      Count2);
171 
172 static void
173 ApCheckPackageList (
174     const char                  *PredefinedName,
175     ACPI_PARSE_OBJECT           *ParentOp,
176     const ACPI_PREDEFINED_INFO  *Package,
177     UINT32                      StartIndex,
178     UINT32                      Count);
179 
180 static void
181 ApPackageTooSmall (
182     const char                  *PredefinedName,
183     ACPI_PARSE_OBJECT           *Op,
184     UINT32                      Count,
185     UINT32                      ExpectedCount);
186 
187 static void
188 ApZeroLengthPackage (
189     const char                  *PredefinedName,
190     ACPI_PARSE_OBJECT           *Op);
191 
192 static void
193 ApPackageTooLarge (
194     const char                  *PredefinedName,
195     ACPI_PARSE_OBJECT           *Op,
196     UINT32                      Count,
197     UINT32                      ExpectedCount);
198 
199 static void
200 ApCustomPackage (
201     ACPI_PARSE_OBJECT           *ParentOp,
202     const ACPI_PREDEFINED_INFO  *Predefined);
203 
204 
205 /*******************************************************************************
206  *
207  * FUNCTION:    ApCheckPackage
208  *
209  * PARAMETERS:  ParentOp            - Parser op for the package
210  *              Predefined          - Pointer to package-specific info for
211  *                                    the method
212  *
213  * RETURN:      None
214  *
215  * DESCRIPTION: Top-level validation for predefined name return package
216  *              objects.
217  *
218  ******************************************************************************/
219 
220 void
ApCheckPackage(ACPI_PARSE_OBJECT * ParentOp,const ACPI_PREDEFINED_INFO * Predefined)221 ApCheckPackage (
222     ACPI_PARSE_OBJECT           *ParentOp,
223     const ACPI_PREDEFINED_INFO  *Predefined)
224 {
225     ACPI_PARSE_OBJECT           *Op;
226     const ACPI_PREDEFINED_INFO  *Package;
227     ACPI_STATUS                 Status;
228     UINT32                      ExpectedCount;
229     UINT32                      Count;
230     UINT32                      i;
231 
232 
233     /* The package info for this name is in the next table entry */
234 
235     Package = Predefined + 1;
236 
237     /* First child is the package length */
238 
239     Op = ParentOp->Asl.Child;
240     Count = (UINT32) Op->Asl.Value.Integer;
241 
242     /*
243      * Many of the variable-length top-level packages are allowed to simply
244      * have zero elements. This allows the BIOS to tell the host that even
245      * though the predefined name/method exists, the feature is not supported.
246      * Other package types require one or more elements. In any case, there
247      * is no need to continue validation.
248      */
249     if (!Count)
250     {
251         switch (Package->RetInfo.Type)
252         {
253         case ACPI_PTYPE1_FIXED:
254         case ACPI_PTYPE1_OPTION:
255         case ACPI_PTYPE2_PKG_COUNT:
256         case ACPI_PTYPE2_REV_FIXED:
257 
258             ApZeroLengthPackage (Predefined->Info.Name, ParentOp);
259             break;
260 
261         case ACPI_PTYPE1_VAR:
262         case ACPI_PTYPE2:
263         case ACPI_PTYPE2_COUNT:
264         case ACPI_PTYPE2_FIXED:
265         case ACPI_PTYPE2_MIN:
266         case ACPI_PTYPE2_FIX_VAR:
267         case ACPI_PTYPE2_VAR_VAR:
268         default:
269 
270             break;
271         }
272 
273         return;
274     }
275 
276     /* Get the first element of the package */
277 
278     Op = Op->Asl.Next;
279 
280     /* Decode the package type */
281 
282     switch (Package->RetInfo.Type)
283     {
284     case ACPI_PTYPE_CUSTOM:
285 
286         ApCustomPackage (ParentOp, Predefined);
287         break;
288 
289     case ACPI_PTYPE1_FIXED:
290         /*
291          * The package count is fixed and there are no subpackages
292          *
293          * If package is too small, exit.
294          * If package is larger than expected, issue warning but continue
295          */
296         ExpectedCount = Package->RetInfo.Count1 + Package->RetInfo.Count2;
297         if (Count < ExpectedCount)
298         {
299             goto PackageTooSmall;
300         }
301         else if (Count > ExpectedCount)
302         {
303             ApPackageTooLarge (Predefined->Info.Name, ParentOp,
304                 Count, ExpectedCount);
305         }
306 
307         /* Validate all elements of the package */
308 
309         ApCheckPackageElements (Predefined->Info.Name, Op,
310             Package->RetInfo.ObjectType1, Package->RetInfo.Count1,
311             Package->RetInfo.ObjectType2, Package->RetInfo.Count2);
312         break;
313 
314     case ACPI_PTYPE1_VAR:
315         /*
316          * The package count is variable, there are no subpackages,
317          * and all elements must be of the same type
318          */
319         for (i = 0; i < Count; i++)
320         {
321             ApCheckObjectType (Predefined->Info.Name, Op,
322                 Package->RetInfo.ObjectType1, i);
323             Op = Op->Asl.Next;
324         }
325         break;
326 
327     case ACPI_PTYPE1_OPTION:
328         /*
329          * The package count is variable, there are no subpackages.
330          * There are a fixed number of required elements, and a variable
331          * number of optional elements.
332          *
333          * Check if package is at least as large as the minimum required
334          */
335         ExpectedCount = Package->RetInfo3.Count;
336         if (Count < ExpectedCount)
337         {
338             goto PackageTooSmall;
339         }
340 
341         /* Variable number of sub-objects */
342 
343         for (i = 0; i < Count; i++)
344         {
345             if (i < Package->RetInfo3.Count)
346             {
347                 /* These are the required package elements (0, 1, or 2) */
348 
349                 ApCheckObjectType (Predefined->Info.Name, Op,
350                     Package->RetInfo3.ObjectType[i], i);
351             }
352             else
353             {
354                 /* These are the optional package elements */
355 
356                 ApCheckObjectType (Predefined->Info.Name, Op,
357                     Package->RetInfo3.TailObjectType, i);
358             }
359 
360             Op = Op->Asl.Next;
361         }
362         break;
363 
364     case ACPI_PTYPE2_REV_FIXED:
365 
366         /* First element is the (Integer) revision */
367 
368         ApCheckObjectType (Predefined->Info.Name, Op,
369             ACPI_RTYPE_INTEGER, 0);
370 
371         Op = Op->Asl.Next;
372         Count--;
373 
374         /* Examine the subpackages */
375 
376         ApCheckPackageList (Predefined->Info.Name, Op,
377             Package, 1, Count);
378         break;
379 
380     case ACPI_PTYPE2_PKG_COUNT:
381 
382         /* First element is the (Integer) count of subpackages to follow */
383 
384         Status = ApCheckObjectType (Predefined->Info.Name, Op,
385             ACPI_RTYPE_INTEGER, 0);
386 
387         /* We must have an integer count from above (otherwise, use Count) */
388 
389         if (ACPI_SUCCESS (Status))
390         {
391             /*
392              * Count cannot be larger than the parent package length, but
393              * allow it to be smaller. The >= accounts for the Integer above.
394              */
395             ExpectedCount = (UINT32) Op->Asl.Value.Integer;
396             if (ExpectedCount >= Count)
397             {
398                 goto PackageTooSmall;
399             }
400 
401             Count = ExpectedCount;
402         }
403 
404         Op = Op->Asl.Next;
405 
406         /* Examine the subpackages */
407 
408         ApCheckPackageList (Predefined->Info.Name, Op,
409             Package, 1, Count);
410         break;
411 
412     case ACPI_PTYPE2_UUID_PAIR:
413 
414         /* The package contains a variable list of UUID Buffer/Package pairs */
415 
416         /* The length of the package must be even */
417 
418         if (Count & 1)
419         {
420             sprintf (MsgBuffer, "%4.4s: Package length, %d, must be even.",
421                 Predefined->Info.Name, Count);
422 
423             AslError (ASL_ERROR, ASL_MSG_RESERVED_PACKAGE_LENGTH,
424                 ParentOp->Asl.Child, MsgBuffer);
425         }
426 
427         /* Validate the alternating types */
428 
429         for (i = 0; i < Count; ++i)
430         {
431             if (i & 1)
432             {
433                 ApCheckObjectType (Predefined->Info.Name, Op,
434                     Package->RetInfo.ObjectType2, i);
435             }
436             else
437             {
438                 ApCheckObjectType (Predefined->Info.Name, Op,
439                     Package->RetInfo.ObjectType1, i);
440             }
441 
442             Op = Op->Asl.Next;
443         }
444 
445         break;
446 
447     case ACPI_PTYPE2_VAR_VAR:
448 
449         /* Check for minimum size (ints at beginning + 1 subpackage) */
450 
451         ExpectedCount = Package->RetInfo4.Count1 + 1;
452         if (Count < ExpectedCount)
453         {
454             goto PackageTooSmall;
455         }
456 
457         /* Check the non-package elements at beginning of main package */
458 
459         for (i = 0; i < Package->RetInfo4.Count1; ++i)
460         {
461             Status = ApCheckObjectType (Predefined->Info.Name, Op,
462                 Package->RetInfo4.ObjectType1, i);
463             Op = Op->Asl.Next;
464         }
465 
466         /* Examine the variable-length list of subpackages */
467 
468         ApCheckPackageList (Predefined->Info.Name, Op,
469             Package, Package->RetInfo4.Count1, Count);
470 
471         break;
472 
473     case ACPI_PTYPE2:
474     case ACPI_PTYPE2_FIXED:
475     case ACPI_PTYPE2_MIN:
476     case ACPI_PTYPE2_COUNT:
477     case ACPI_PTYPE2_FIX_VAR:
478         /*
479          * These types all return a single Package that consists of a
480          * variable number of subpackages.
481          */
482 
483         /* Examine the subpackages */
484 
485         ApCheckPackageList (Predefined->Info.Name, Op,
486             Package, 0, Count);
487         break;
488 
489     default:
490         return;
491     }
492 
493     return;
494 
495 PackageTooSmall:
496     ApPackageTooSmall (Predefined->Info.Name, ParentOp,
497         Count, ExpectedCount);
498 }
499 
500 
501 /*******************************************************************************
502  *
503  * FUNCTION:    ApCustomPackage
504  *
505  * PARAMETERS:  ParentOp            - Parse op for the package
506  *              Predefined          - Pointer to package-specific info for
507  *                                    the method
508  *
509  * RETURN:      None
510  *
511  * DESCRIPTION: Validate packages that don't fit into the standard model and
512  *              require custom code.
513  *
514  * NOTE: Currently used for the _BIX method only. When needed for two or more
515  * methods, probably a detect/dispatch mechanism will be required.
516  *
517  ******************************************************************************/
518 
519 static void
ApCustomPackage(ACPI_PARSE_OBJECT * ParentOp,const ACPI_PREDEFINED_INFO * Predefined)520 ApCustomPackage (
521     ACPI_PARSE_OBJECT           *ParentOp,
522     const ACPI_PREDEFINED_INFO  *Predefined)
523 {
524     ACPI_PARSE_OBJECT           *Op;
525     UINT32                      Count;
526     UINT32                      ExpectedCount;
527     UINT32                      Version;
528 
529 
530     /* First child is the package length */
531 
532     Op = ParentOp->Asl.Child;
533     Count = (UINT32) Op->Asl.Value.Integer;
534 
535     /* Get the version number, must be Integer */
536 
537     Op = Op->Asl.Next;
538     Version = (UINT32) Op->Asl.Value.Integer;
539     if (Op->Asl.ParseOpcode != PARSEOP_INTEGER)
540     {
541         AslError (ASL_ERROR, ASL_MSG_RESERVED_OPERAND_TYPE, Op, MsgBuffer);
542         return;
543     }
544 
545     /* Validate count (# of elements) */
546 
547     ExpectedCount = 21;         /* Version 1 */
548     if (Version == 0)
549     {
550         ExpectedCount = 20;     /* Version 0 */
551     }
552 
553     if (Count < ExpectedCount)
554     {
555         ApPackageTooSmall (Predefined->Info.Name, ParentOp,
556             Count, ExpectedCount);
557         return;
558     }
559     else if (Count > ExpectedCount)
560     {
561         ApPackageTooLarge (Predefined->Info.Name, ParentOp,
562             Count, ExpectedCount);
563     }
564 
565     /* Validate all elements of the package */
566 
567     Op = ApCheckPackageElements (Predefined->Info.Name, Op,
568         ACPI_RTYPE_INTEGER, 16,
569         ACPI_RTYPE_STRING, 4);
570 
571     /* Version 1 has a single trailing integer */
572 
573     if (Version > 0)
574     {
575         ApCheckPackageElements (Predefined->Info.Name, Op,
576             ACPI_RTYPE_INTEGER, 1, 0, 0);
577     }
578 }
579 
580 
581 /*******************************************************************************
582  *
583  * FUNCTION:    ApCheckPackageElements
584  *
585  * PARAMETERS:  PredefinedName      - Name of the predefined object
586  *              Op                  - Parser op for the package
587  *              Type1               - Object type for first group
588  *              Count1              - Count for first group
589  *              Type2               - Object type for second group
590  *              Count2              - Count for second group
591  *
592  * RETURN:      Next Op peer in the parse tree, after all specified elements
593  *              have been validated. Used for multiple validations (calls
594  *              to this function).
595  *
596  * DESCRIPTION: Validate all elements of a package. Works with packages that
597  *              are defined to contain up to two groups of different object
598  *              types.
599  *
600  ******************************************************************************/
601 
602 static ACPI_PARSE_OBJECT *
ApCheckPackageElements(const char * PredefinedName,ACPI_PARSE_OBJECT * Op,UINT8 Type1,UINT32 Count1,UINT8 Type2,UINT32 Count2)603 ApCheckPackageElements (
604     const char              *PredefinedName,
605     ACPI_PARSE_OBJECT       *Op,
606     UINT8                   Type1,
607     UINT32                  Count1,
608     UINT8                   Type2,
609     UINT32                  Count2)
610 {
611     UINT32                  i;
612 
613 
614     /*
615      * Up to two groups of package elements are supported by the data
616      * structure. All elements in each group must be of the same type.
617      * The second group can have a count of zero.
618      *
619      * Aborts check upon a NULL package element, as this means (at compile
620      * time) that the remainder of the package elements are also NULL
621      * (This is the only way to create NULL package elements.)
622      */
623     for (i = 0; (i < Count1) && Op; i++)
624     {
625         ApCheckObjectType (PredefinedName, Op, Type1, i);
626         Op = Op->Asl.Next;
627     }
628 
629     for (i = 0; (i < Count2) && Op; i++)
630     {
631         ApCheckObjectType (PredefinedName, Op, Type2, (i + Count1));
632         Op = Op->Asl.Next;
633     }
634 
635     return (Op);
636 }
637 
638 
639 /*******************************************************************************
640  *
641  * FUNCTION:    ApCheckPackageList
642  *
643  * PARAMETERS:  PredefinedName      - Name of the predefined object
644  *              ParentOp            - Parser op of the parent package
645  *              Package             - Package info for this predefined name
646  *              StartIndex          - Index in parent package where list begins
647  *              ParentCount         - Element count of parent package
648  *
649  * RETURN:      None
650  *
651  * DESCRIPTION: Validate the individual package elements for a predefined name.
652  *              Handles the cases where the predefined name is defined as a
653  *              Package of Packages (subpackages). These are the types:
654  *
655  *              ACPI_PTYPE2
656  *              ACPI_PTYPE2_FIXED
657  *              ACPI_PTYPE2_MIN
658  *              ACPI_PTYPE2_COUNT
659  *              ACPI_PTYPE2_FIX_VAR
660  *              ACPI_PTYPE2_VAR_VAR
661  *
662  ******************************************************************************/
663 
664 static void
ApCheckPackageList(const char * PredefinedName,ACPI_PARSE_OBJECT * ParentOp,const ACPI_PREDEFINED_INFO * Package,UINT32 StartIndex,UINT32 ParentCount)665 ApCheckPackageList (
666     const char                  *PredefinedName,
667     ACPI_PARSE_OBJECT           *ParentOp,
668     const ACPI_PREDEFINED_INFO  *Package,
669     UINT32                      StartIndex,
670     UINT32                      ParentCount)
671 {
672     ACPI_PARSE_OBJECT           *SubPackageOp = ParentOp;
673     ACPI_PARSE_OBJECT           *Op;
674     ACPI_STATUS                 Status;
675     UINT32                      Count;
676     UINT32                      ExpectedCount;
677     UINT32                      i;
678     UINT32                      j;
679 
680 
681     /*
682      * Validate each subpackage in the parent Package
683      *
684      * Note: We ignore NULL package elements on the assumption that
685      * they will be initialized by the BIOS or other ASL code.
686      */
687     for (i = 0; (i < ParentCount) && SubPackageOp; i++)
688     {
689         /* Each object in the list must be of type Package */
690 
691         Status = ApCheckObjectType (PredefinedName, SubPackageOp,
692             ACPI_RTYPE_PACKAGE, i + StartIndex);
693         if (ACPI_FAILURE (Status))
694         {
695             goto NextSubpackage;
696         }
697 
698         /* Examine the different types of expected subpackages */
699 
700         Op = SubPackageOp->Asl.Child;
701 
702         /* First child is the package length */
703 
704         Count = (UINT32) Op->Asl.Value.Integer;
705         Op = Op->Asl.Next;
706 
707         /*
708          * Most subpackage must have at least one element, with
709          * only rare exceptions. (_RDI)
710          */
711         if (!Count &&
712             (Package->RetInfo.Type != ACPI_PTYPE2_VAR_VAR))
713         {
714             ApZeroLengthPackage (PredefinedName, SubPackageOp);
715             goto NextSubpackage;
716         }
717 
718         /*
719          * Decode the package type.
720          * PTYPE2 indicates that a "package of packages" is expected for
721          * this name. The various flavors of PTYPE2 indicate the number
722          * and format of the subpackages.
723          */
724         switch (Package->RetInfo.Type)
725         {
726         case ACPI_PTYPE2:
727         case ACPI_PTYPE2_PKG_COUNT:
728         case ACPI_PTYPE2_REV_FIXED:
729 
730             /* Each subpackage has a fixed number of elements */
731 
732             ExpectedCount = Package->RetInfo.Count1 + Package->RetInfo.Count2;
733             if (Count < ExpectedCount)
734             {
735                 ApPackageTooSmall (PredefinedName, SubPackageOp,
736                     Count, ExpectedCount);
737                 break;
738             }
739             if (Count > ExpectedCount)
740             {
741                 ApPackageTooLarge (PredefinedName, SubPackageOp,
742                     Count, ExpectedCount);
743                 break;
744             }
745 
746             ApCheckPackageElements (PredefinedName, Op,
747                 Package->RetInfo.ObjectType1, Package->RetInfo.Count1,
748                 Package->RetInfo.ObjectType2, Package->RetInfo.Count2);
749             break;
750 
751         case ACPI_PTYPE2_FIX_VAR:
752             /*
753              * Each subpackage has a fixed number of elements and an
754              * optional element
755              */
756             ExpectedCount = Package->RetInfo.Count1 + Package->RetInfo.Count2;
757             if (Count < ExpectedCount)
758             {
759                 ApPackageTooSmall (PredefinedName, SubPackageOp,
760                     Count, ExpectedCount);
761                 break;
762             }
763 
764             ApCheckPackageElements (PredefinedName, Op,
765                 Package->RetInfo.ObjectType1, Package->RetInfo.Count1,
766                 Package->RetInfo.ObjectType2,
767                 Count - Package->RetInfo.Count1);
768             break;
769 
770         case ACPI_PTYPE2_VAR_VAR:
771             /*
772              * Must have at least the minimum number elements.
773              * A zero PkgCount means the number of elements is variable.
774              */
775             ExpectedCount = Package->RetInfo4.PkgCount;
776             if (ExpectedCount && (Count < ExpectedCount))
777             {
778                 ApPackageTooSmall (PredefinedName, SubPackageOp,
779                     Count, 1);
780                 break;
781             }
782 
783             ApCheckPackageElements (PredefinedName, Op,
784                 Package->RetInfo4.SubObjectTypes,
785                 Package->RetInfo4.PkgCount,
786                 0, 0);
787             break;
788 
789         case ACPI_PTYPE2_FIXED:
790 
791             /* Each subpackage has a fixed length */
792 
793             ExpectedCount = Package->RetInfo2.Count;
794             if (Count < ExpectedCount)
795             {
796                 ApPackageTooSmall (PredefinedName, SubPackageOp,
797                     Count, ExpectedCount);
798                 break;
799             }
800             if (Count > ExpectedCount)
801             {
802                 ApPackageTooLarge (PredefinedName, SubPackageOp,
803                     Count, ExpectedCount);
804                 break;
805             }
806 
807             /* Check each object/type combination */
808 
809             for (j = 0; j < ExpectedCount; j++)
810             {
811                 ApCheckObjectType (PredefinedName, Op,
812                     Package->RetInfo2.ObjectType[j], j);
813 
814                 Op = Op->Asl.Next;
815             }
816             break;
817 
818         case ACPI_PTYPE2_MIN:
819 
820             /* Each subpackage has a variable but minimum length */
821 
822             ExpectedCount = Package->RetInfo.Count1;
823             if (Count < ExpectedCount)
824             {
825                 ApPackageTooSmall (PredefinedName, SubPackageOp,
826                     Count, ExpectedCount);
827                 break;
828             }
829 
830             /* Check the type of each subpackage element */
831 
832             ApCheckPackageElements (PredefinedName, Op,
833                 Package->RetInfo.ObjectType1, Count, 0, 0);
834             break;
835 
836         case ACPI_PTYPE2_COUNT:
837             /*
838              * First element is the (Integer) count of elements, including
839              * the count field (the ACPI name is NumElements)
840              */
841             Status = ApCheckObjectType (PredefinedName, Op,
842                 ACPI_RTYPE_INTEGER, 0);
843 
844             /* We must have an integer count from above (otherwise, use Count) */
845 
846             if (ACPI_SUCCESS (Status))
847             {
848                 /*
849                  * Make sure package is large enough for the Count and is
850                  * is as large as the minimum size
851                  */
852                 ExpectedCount = (UINT32) Op->Asl.Value.Integer;
853 
854                 if (Count < ExpectedCount)
855                 {
856                     ApPackageTooSmall (PredefinedName, SubPackageOp,
857                         Count, ExpectedCount);
858                     break;
859                 }
860                 else if (Count > ExpectedCount)
861                 {
862                     ApPackageTooLarge (PredefinedName, SubPackageOp,
863                         Count, ExpectedCount);
864                 }
865 
866                 /* Some names of this type have a minimum length */
867 
868                 if (Count < Package->RetInfo.Count1)
869                 {
870                     ExpectedCount = Package->RetInfo.Count1;
871                     ApPackageTooSmall (PredefinedName, SubPackageOp,
872                         Count, ExpectedCount);
873                     break;
874                 }
875 
876                 Count = ExpectedCount;
877             }
878 
879             /* Check the type of each subpackage element */
880 
881             Op = Op->Asl.Next;
882             ApCheckPackageElements (PredefinedName, Op,
883                 Package->RetInfo.ObjectType1, (Count - 1), 0, 0);
884             break;
885 
886         default:
887             break;
888         }
889 
890 NextSubpackage:
891         SubPackageOp = SubPackageOp->Asl.Next;
892     }
893 }
894 
895 
896 /*******************************************************************************
897  *
898  * FUNCTION:    ApPackageTooSmall
899  *
900  * PARAMETERS:  PredefinedName      - Name of the predefined object
901  *              Op                  - Current parser op
902  *              Count               - Actual package element count
903  *              ExpectedCount       - Expected package element count
904  *
905  * RETURN:      None
906  *
907  * DESCRIPTION: Issue error message for a package that is smaller than
908  *              required.
909  *
910  ******************************************************************************/
911 
912 static void
ApPackageTooSmall(const char * PredefinedName,ACPI_PARSE_OBJECT * Op,UINT32 Count,UINT32 ExpectedCount)913 ApPackageTooSmall (
914     const char                  *PredefinedName,
915     ACPI_PARSE_OBJECT           *Op,
916     UINT32                      Count,
917     UINT32                      ExpectedCount)
918 {
919 
920     sprintf (MsgBuffer, "%s: length %u, required minimum is %u",
921         PredefinedName, Count, ExpectedCount);
922 
923     AslError (ASL_ERROR, ASL_MSG_RESERVED_PACKAGE_LENGTH, Op, MsgBuffer);
924 }
925 
926 
927 /*******************************************************************************
928  *
929  * FUNCTION:    ApZeroLengthPackage
930  *
931  * PARAMETERS:  PredefinedName      - Name of the predefined object
932  *              Op                  - Current parser op
933  *
934  * RETURN:      None
935  *
936  * DESCRIPTION: Issue error message for a zero-length package (a package that
937  *              is required to have a non-zero length). Variable length
938  *              packages seem to be allowed to have zero length, however.
939  *              Even if not allowed, BIOS code does it.
940  *
941  ******************************************************************************/
942 
943 static void
ApZeroLengthPackage(const char * PredefinedName,ACPI_PARSE_OBJECT * Op)944 ApZeroLengthPackage (
945     const char                  *PredefinedName,
946     ACPI_PARSE_OBJECT           *Op)
947 {
948 
949     sprintf (MsgBuffer, "%s: length is zero", PredefinedName);
950 
951     AslError (ASL_ERROR, ASL_MSG_RESERVED_PACKAGE_LENGTH, Op, MsgBuffer);
952 }
953 
954 
955 /*******************************************************************************
956  *
957  * FUNCTION:    ApPackageTooLarge
958  *
959  * PARAMETERS:  PredefinedName      - Name of the predefined object
960  *              Op                  - Current parser op
961  *              Count               - Actual package element count
962  *              ExpectedCount       - Expected package element count
963  *
964  * RETURN:      None
965  *
966  * DESCRIPTION: Issue a remark for a package that is larger than expected.
967  *
968  ******************************************************************************/
969 
970 static void
ApPackageTooLarge(const char * PredefinedName,ACPI_PARSE_OBJECT * Op,UINT32 Count,UINT32 ExpectedCount)971 ApPackageTooLarge (
972     const char                  *PredefinedName,
973     ACPI_PARSE_OBJECT           *Op,
974     UINT32                      Count,
975     UINT32                      ExpectedCount)
976 {
977 
978     sprintf (MsgBuffer, "%s: length is %u, only %u required",
979         PredefinedName, Count, ExpectedCount);
980 
981     AslError (ASL_REMARK, ASL_MSG_RESERVED_PACKAGE_LENGTH, Op, MsgBuffer);
982 }
983