xref: /freebsd/sys/contrib/dev/acpica/compiler/aslprepkg.c (revision 96190b4fef3b4a0cc3ca0606b0c4e3e69a5e6717)
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 - 2023, 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 <contrib/dev/acpica/compiler/aslcompiler.h>
153 #include "aslcompiler.y.h"
154 #include <contrib/dev/acpica/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
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             if (!Op)
322             {
323                 /*
324                  * If we get to this point, it means that the package length
325                  * is larger than the initializer list. Stop processing the
326                  * package and return because we have run out of package
327                  * elements to analyze.
328                  */
329                 return;
330             }
331 
332             ApCheckObjectType (Predefined->Info.Name, Op,
333                 Package->RetInfo.ObjectType1, i);
334             Op = Op->Asl.Next;
335         }
336         break;
337 
338     case ACPI_PTYPE1_OPTION:
339         /*
340          * The package count is variable, there are no subpackages.
341          * There are a fixed number of required elements, and a variable
342          * number of optional elements.
343          *
344          * Check if package is at least as large as the minimum required
345          */
346         ExpectedCount = Package->RetInfo3.Count;
347         if (Count < ExpectedCount)
348         {
349             goto PackageTooSmall;
350         }
351 
352         /* Variable number of sub-objects */
353 
354         for (i = 0; i < Count; i++)
355         {
356             if (i < Package->RetInfo3.Count)
357             {
358                 /* These are the required package elements (0, 1, or 2) */
359 
360                 ApCheckObjectType (Predefined->Info.Name, Op,
361                     Package->RetInfo3.ObjectType[i], i);
362             }
363             else
364             {
365                 /* These are the optional package elements */
366 
367                 ApCheckObjectType (Predefined->Info.Name, Op,
368                     Package->RetInfo3.TailObjectType, i);
369             }
370 
371             Op = Op->Asl.Next;
372         }
373         break;
374 
375     case ACPI_PTYPE2_REV_FIXED:
376 
377         /* First element is the (Integer) revision */
378 
379         ApCheckObjectType (Predefined->Info.Name, Op,
380             ACPI_RTYPE_INTEGER, 0);
381 
382         Op = Op->Asl.Next;
383         Count--;
384 
385         /* Examine the subpackages */
386 
387         ApCheckPackageList (Predefined->Info.Name, Op,
388             Package, 1, Count);
389         break;
390 
391     case ACPI_PTYPE2_PKG_COUNT:
392 
393         /* First element is the (Integer) count of subpackages to follow */
394 
395         Status = ApCheckObjectType (Predefined->Info.Name, Op,
396             ACPI_RTYPE_INTEGER, 0);
397 
398         /* We must have an integer count from above (otherwise, use Count) */
399 
400         if (ACPI_SUCCESS (Status))
401         {
402             /*
403              * Count cannot be larger than the parent package length, but
404              * allow it to be smaller. The >= accounts for the Integer above.
405              */
406             ExpectedCount = (UINT32) Op->Asl.Value.Integer;
407             if (ExpectedCount >= Count)
408             {
409                 goto PackageTooSmall;
410             }
411 
412             Count = ExpectedCount;
413         }
414 
415         Op = Op->Asl.Next;
416 
417         /* Examine the subpackages */
418 
419         ApCheckPackageList (Predefined->Info.Name, Op,
420             Package, 1, Count);
421         break;
422 
423     case ACPI_PTYPE2_UUID_PAIR:
424 
425         /* The package contains a variable list of UUID Buffer/Package pairs */
426 
427         /* The length of the package must be even */
428 
429         if (Count & 1)
430         {
431             sprintf (AslGbl_MsgBuffer, "%4.4s: Package length, %d, must be even.",
432                 Predefined->Info.Name, Count);
433 
434             AslError (ASL_ERROR, ASL_MSG_RESERVED_PACKAGE_LENGTH,
435                 ParentOp->Asl.Child, AslGbl_MsgBuffer);
436         }
437 
438         /* Validate the alternating types */
439 
440         for (i = 0; i < Count; ++i)
441         {
442             if (i & 1)
443             {
444                 ApCheckObjectType (Predefined->Info.Name, Op,
445                     Package->RetInfo.ObjectType2, i);
446             }
447             else
448             {
449                 ApCheckObjectType (Predefined->Info.Name, Op,
450                     Package->RetInfo.ObjectType1, i);
451             }
452 
453             Op = Op->Asl.Next;
454         }
455 
456         break;
457 
458     case ACPI_PTYPE2_VAR_VAR:
459 
460         /* Check for minimum size (ints at beginning + 1 subpackage) */
461 
462         ExpectedCount = Package->RetInfo4.Count1 + 1;
463         if (Count < ExpectedCount)
464         {
465             goto PackageTooSmall;
466         }
467 
468         /* Check the non-package elements at beginning of main package */
469 
470         for (i = 0; i < Package->RetInfo4.Count1; ++i)
471         {
472             ApCheckObjectType (Predefined->Info.Name, Op,
473                 Package->RetInfo4.ObjectType1, i);
474             Op = Op->Asl.Next;
475         }
476 
477         /* Examine the variable-length list of subpackages */
478 
479         ApCheckPackageList (Predefined->Info.Name, Op,
480             Package, Package->RetInfo4.Count1, Count);
481 
482         break;
483 
484     case ACPI_PTYPE2:
485     case ACPI_PTYPE2_FIXED:
486     case ACPI_PTYPE2_MIN:
487     case ACPI_PTYPE2_COUNT:
488     case ACPI_PTYPE2_FIX_VAR:
489         /*
490          * These types all return a single Package that consists of a
491          * variable number of subpackages.
492          */
493 
494         /* Examine the subpackages */
495 
496         ApCheckPackageList (Predefined->Info.Name, Op,
497             Package, 0, Count);
498         break;
499 
500     default:
501         return;
502     }
503 
504     return;
505 
506 PackageTooSmall:
507     ApPackageTooSmall (Predefined->Info.Name, ParentOp,
508         Count, ExpectedCount);
509 }
510 
511 
512 /*******************************************************************************
513  *
514  * FUNCTION:    ApCustomPackage
515  *
516  * PARAMETERS:  ParentOp            - Parse op for the package
517  *              Predefined          - Pointer to package-specific info for
518  *                                    the method
519  *
520  * RETURN:      None
521  *
522  * DESCRIPTION: Validate packages that don't fit into the standard model and
523  *              require custom code.
524  *
525  * NOTE: Currently used for the _BIX method only. When needed for two or more
526  * methods, probably a detect/dispatch mechanism will be required.
527  *
528  ******************************************************************************/
529 
530 static void
531 ApCustomPackage (
532     ACPI_PARSE_OBJECT           *ParentOp,
533     const ACPI_PREDEFINED_INFO  *Predefined)
534 {
535     ACPI_PARSE_OBJECT           *Op;
536     UINT32                      Count;
537     UINT32                      ExpectedCount;
538     UINT32                      Version;
539 
540 
541     /* First child is the package length */
542 
543     Op = ParentOp->Asl.Child;
544     Count = (UINT32) Op->Asl.Value.Integer;
545 
546     /* Get the version number, must be Integer */
547 
548     Op = Op->Asl.Next;
549     Version = (UINT32) Op->Asl.Value.Integer;
550     if (Op->Asl.ParseOpcode != PARSEOP_INTEGER)
551     {
552         AslError (ASL_ERROR, ASL_MSG_RESERVED_OPERAND_TYPE, Op, AslGbl_MsgBuffer);
553         return;
554     }
555 
556     /* Validate count (# of elements) */
557 
558     ExpectedCount = 21;         /* Version 1 */
559     if (Version == 0)
560     {
561         ExpectedCount = 20;     /* Version 0 */
562     }
563 
564     if (Count < ExpectedCount)
565     {
566         ApPackageTooSmall (Predefined->Info.Name, ParentOp,
567             Count, ExpectedCount);
568         return;
569     }
570     else if (Count > ExpectedCount)
571     {
572         ApPackageTooLarge (Predefined->Info.Name, ParentOp,
573             Count, ExpectedCount);
574     }
575 
576     /* Validate all elements of the package */
577 
578     Op = ApCheckPackageElements (Predefined->Info.Name, Op,
579         ACPI_RTYPE_INTEGER, 16,
580         ACPI_RTYPE_STRING, 4);
581 
582     /* Version 1 has a single trailing integer */
583 
584     if (Version > 0)
585     {
586         ApCheckPackageElements (Predefined->Info.Name, Op,
587             ACPI_RTYPE_INTEGER, 1, 0, 0);
588     }
589 }
590 
591 
592 /*******************************************************************************
593  *
594  * FUNCTION:    ApCheckPackageElements
595  *
596  * PARAMETERS:  PredefinedName      - Name of the predefined object
597  *              Op                  - Parser op for the package
598  *              Type1               - Object type for first group
599  *              Count1              - Count for first group
600  *              Type2               - Object type for second group
601  *              Count2              - Count for second group
602  *
603  * RETURN:      Next Op peer in the parse tree, after all specified elements
604  *              have been validated. Used for multiple validations (calls
605  *              to this function).
606  *
607  * DESCRIPTION: Validate all elements of a package. Works with packages that
608  *              are defined to contain up to two groups of different object
609  *              types.
610  *
611  ******************************************************************************/
612 
613 static ACPI_PARSE_OBJECT *
614 ApCheckPackageElements (
615     const char              *PredefinedName,
616     ACPI_PARSE_OBJECT       *Op,
617     UINT8                   Type1,
618     UINT32                  Count1,
619     UINT8                   Type2,
620     UINT32                  Count2)
621 {
622     UINT32                  i;
623 
624 
625     /*
626      * Up to two groups of package elements are supported by the data
627      * structure. All elements in each group must be of the same type.
628      * The second group can have a count of zero.
629      *
630      * Aborts check upon a NULL package element, as this means (at compile
631      * time) that the remainder of the package elements are also NULL
632      * (This is the only way to create NULL package elements.)
633      */
634     for (i = 0; (i < Count1) && Op; i++)
635     {
636         ApCheckObjectType (PredefinedName, Op, Type1, i);
637         Op = Op->Asl.Next;
638     }
639 
640     for (i = 0; (i < Count2) && Op; i++)
641     {
642         ApCheckObjectType (PredefinedName, Op, Type2, (i + Count1));
643         Op = Op->Asl.Next;
644     }
645 
646     return (Op);
647 }
648 
649 
650 /*******************************************************************************
651  *
652  * FUNCTION:    ApCheckPackageList
653  *
654  * PARAMETERS:  PredefinedName      - Name of the predefined object
655  *              ParentOp            - Parser op of the parent package
656  *              Package             - Package info for this predefined name
657  *              StartIndex          - Index in parent package where list begins
658  *              ParentCount         - Element count of parent package
659  *
660  * RETURN:      None
661  *
662  * DESCRIPTION: Validate the individual package elements for a predefined name.
663  *              Handles the cases where the predefined name is defined as a
664  *              Package of Packages (subpackages). These are the types:
665  *
666  *              ACPI_PTYPE2
667  *              ACPI_PTYPE2_FIXED
668  *              ACPI_PTYPE2_MIN
669  *              ACPI_PTYPE2_COUNT
670  *              ACPI_PTYPE2_FIX_VAR
671  *              ACPI_PTYPE2_VAR_VAR
672  *
673  ******************************************************************************/
674 
675 static void
676 ApCheckPackageList (
677     const char                  *PredefinedName,
678     ACPI_PARSE_OBJECT           *ParentOp,
679     const ACPI_PREDEFINED_INFO  *Package,
680     UINT32                      StartIndex,
681     UINT32                      ParentCount)
682 {
683     ACPI_PARSE_OBJECT           *SubPackageOp = ParentOp;
684     ACPI_PARSE_OBJECT           *Op;
685     ACPI_STATUS                 Status;
686     UINT32                      Count;
687     UINT32                      ExpectedCount;
688     UINT32                      i;
689     UINT32                      j;
690 
691 
692     /*
693      * Validate each subpackage in the parent Package
694      *
695      * Note: We ignore NULL package elements on the assumption that
696      * they will be initialized by the BIOS or other ASL code.
697      */
698     for (i = 0; (i < ParentCount) && SubPackageOp; i++)
699     {
700         /* Each object in the list must be of type Package */
701 
702         Status = ApCheckObjectType (PredefinedName, SubPackageOp,
703             ACPI_RTYPE_PACKAGE, i + StartIndex);
704         if (ACPI_FAILURE (Status))
705         {
706             goto NextSubpackage;
707         }
708 
709         /* Examine the different types of expected subpackages */
710 
711         Op = SubPackageOp->Asl.Child;
712 
713         /* First child is the package length */
714 
715         Count = (UINT32) Op->Asl.Value.Integer;
716         Op = Op->Asl.Next;
717 
718         /*
719          * Most subpackage must have at least one element, with
720          * only rare exceptions. (_RDI)
721          */
722         if (!Count &&
723             (Package->RetInfo.Type != ACPI_PTYPE2_VAR_VAR))
724         {
725             ApZeroLengthPackage (PredefinedName, SubPackageOp);
726             goto NextSubpackage;
727         }
728 
729         /*
730          * Decode the package type.
731          * PTYPE2 indicates that a "package of packages" is expected for
732          * this name. The various flavors of PTYPE2 indicate the number
733          * and format of the subpackages.
734          */
735         switch (Package->RetInfo.Type)
736         {
737         case ACPI_PTYPE2:
738         case ACPI_PTYPE2_PKG_COUNT:
739         case ACPI_PTYPE2_REV_FIXED:
740 
741             /* Each subpackage has a fixed number of elements */
742 
743             ExpectedCount = Package->RetInfo.Count1 + Package->RetInfo.Count2;
744             if (Count < ExpectedCount)
745             {
746                 ApPackageTooSmall (PredefinedName, SubPackageOp,
747                     Count, ExpectedCount);
748                 break;
749             }
750             if (Count > ExpectedCount)
751             {
752                 ApPackageTooLarge (PredefinedName, SubPackageOp,
753                     Count, ExpectedCount);
754                 break;
755             }
756 
757             ApCheckPackageElements (PredefinedName, Op,
758                 Package->RetInfo.ObjectType1, Package->RetInfo.Count1,
759                 Package->RetInfo.ObjectType2, Package->RetInfo.Count2);
760             break;
761 
762         case ACPI_PTYPE2_FIX_VAR:
763             /*
764              * Each subpackage has a fixed number of elements and an
765              * optional element
766              */
767             ExpectedCount = Package->RetInfo.Count1 + Package->RetInfo.Count2;
768             if (Count < ExpectedCount)
769             {
770                 ApPackageTooSmall (PredefinedName, SubPackageOp,
771                     Count, ExpectedCount);
772                 break;
773             }
774 
775             ApCheckPackageElements (PredefinedName, Op,
776                 Package->RetInfo.ObjectType1, Package->RetInfo.Count1,
777                 Package->RetInfo.ObjectType2,
778                 Count - Package->RetInfo.Count1);
779             break;
780 
781         case ACPI_PTYPE2_VAR_VAR:
782             /*
783              * Must have at least the minimum number elements.
784              * A zero PkgCount means the number of elements is variable.
785              */
786             ExpectedCount = Package->RetInfo4.PkgCount;
787             if (ExpectedCount && (Count < ExpectedCount))
788             {
789                 ApPackageTooSmall (PredefinedName, SubPackageOp,
790                     Count, 1);
791                 break;
792             }
793 
794             ApCheckPackageElements (PredefinedName, Op,
795                 Package->RetInfo4.SubObjectTypes,
796                 Package->RetInfo4.PkgCount,
797                 0, 0);
798             break;
799 
800         case ACPI_PTYPE2_FIXED:
801 
802             /* Each subpackage has a fixed length */
803 
804             ExpectedCount = Package->RetInfo2.Count;
805             if (Count < ExpectedCount)
806             {
807                 ApPackageTooSmall (PredefinedName, SubPackageOp,
808                     Count, ExpectedCount);
809                 break;
810             }
811             if (Count > ExpectedCount)
812             {
813                 ApPackageTooLarge (PredefinedName, SubPackageOp,
814                     Count, ExpectedCount);
815                 break;
816             }
817 
818             /* Check each object/type combination */
819 
820             for (j = 0; j < ExpectedCount; j++)
821             {
822                 ApCheckObjectType (PredefinedName, Op,
823                     Package->RetInfo2.ObjectType[j], j);
824 
825                 Op = Op->Asl.Next;
826             }
827             break;
828 
829         case ACPI_PTYPE2_MIN:
830 
831             /* Each subpackage has a variable but minimum length */
832 
833             ExpectedCount = Package->RetInfo.Count1;
834             if (Count < ExpectedCount)
835             {
836                 ApPackageTooSmall (PredefinedName, SubPackageOp,
837                     Count, ExpectedCount);
838                 break;
839             }
840 
841             /* Check the type of each subpackage element */
842 
843             ApCheckPackageElements (PredefinedName, Op,
844                 Package->RetInfo.ObjectType1, Count, 0, 0);
845             break;
846 
847         case ACPI_PTYPE2_COUNT:
848             /*
849              * First element is the (Integer) count of elements, including
850              * the count field (the ACPI name is NumElements)
851              */
852             Status = ApCheckObjectType (PredefinedName, Op,
853                 ACPI_RTYPE_INTEGER, 0);
854 
855             /* We must have an integer count from above (otherwise, use Count) */
856 
857             if (ACPI_SUCCESS (Status))
858             {
859                 /*
860                  * Make sure package is large enough for the Count and is
861                  * is as large as the minimum size
862                  */
863                 ExpectedCount = (UINT32) Op->Asl.Value.Integer;
864 
865                 if (Count < ExpectedCount)
866                 {
867                     ApPackageTooSmall (PredefinedName, SubPackageOp,
868                         Count, ExpectedCount);
869                     break;
870                 }
871                 else if (Count > ExpectedCount)
872                 {
873                     ApPackageTooLarge (PredefinedName, SubPackageOp,
874                         Count, ExpectedCount);
875                 }
876 
877                 /* Some names of this type have a minimum length */
878 
879                 if (Count < Package->RetInfo.Count1)
880                 {
881                     ExpectedCount = Package->RetInfo.Count1;
882                     ApPackageTooSmall (PredefinedName, SubPackageOp,
883                         Count, ExpectedCount);
884                     break;
885                 }
886 
887                 Count = ExpectedCount;
888             }
889 
890             /* Check the type of each subpackage element */
891 
892             Op = Op->Asl.Next;
893             ApCheckPackageElements (PredefinedName, Op,
894                 Package->RetInfo.ObjectType1, (Count - 1), 0, 0);
895             break;
896 
897         default:
898             break;
899         }
900 
901 NextSubpackage:
902         SubPackageOp = SubPackageOp->Asl.Next;
903     }
904 }
905 
906 
907 /*******************************************************************************
908  *
909  * FUNCTION:    ApPackageTooSmall
910  *
911  * PARAMETERS:  PredefinedName      - Name of the predefined object
912  *              Op                  - Current parser op
913  *              Count               - Actual package element count
914  *              ExpectedCount       - Expected package element count
915  *
916  * RETURN:      None
917  *
918  * DESCRIPTION: Issue error message for a package that is smaller than
919  *              required.
920  *
921  ******************************************************************************/
922 
923 static void
924 ApPackageTooSmall (
925     const char                  *PredefinedName,
926     ACPI_PARSE_OBJECT           *Op,
927     UINT32                      Count,
928     UINT32                      ExpectedCount)
929 {
930 
931     sprintf (AslGbl_MsgBuffer, "%4.4s: length %u, required minimum is %u",
932         PredefinedName, Count, ExpectedCount);
933 
934     AslError (ASL_ERROR, ASL_MSG_RESERVED_PACKAGE_LENGTH, Op, AslGbl_MsgBuffer);
935 }
936 
937 
938 /*******************************************************************************
939  *
940  * FUNCTION:    ApZeroLengthPackage
941  *
942  * PARAMETERS:  PredefinedName      - Name of the predefined object
943  *              Op                  - Current parser op
944  *
945  * RETURN:      None
946  *
947  * DESCRIPTION: Issue error message for a zero-length package (a package that
948  *              is required to have a non-zero length). Variable length
949  *              packages seem to be allowed to have zero length, however.
950  *              Even if not allowed, BIOS code does it.
951  *
952  ******************************************************************************/
953 
954 static void
955 ApZeroLengthPackage (
956     const char                  *PredefinedName,
957     ACPI_PARSE_OBJECT           *Op)
958 {
959 
960     sprintf (AslGbl_MsgBuffer, "%4.4s: length is zero", PredefinedName);
961 
962     AslError (ASL_ERROR, ASL_MSG_RESERVED_PACKAGE_LENGTH, Op, AslGbl_MsgBuffer);
963 }
964 
965 
966 /*******************************************************************************
967  *
968  * FUNCTION:    ApPackageTooLarge
969  *
970  * PARAMETERS:  PredefinedName      - Name of the predefined object
971  *              Op                  - Current parser op
972  *              Count               - Actual package element count
973  *              ExpectedCount       - Expected package element count
974  *
975  * RETURN:      None
976  *
977  * DESCRIPTION: Issue a remark for a package that is larger than expected.
978  *
979  ******************************************************************************/
980 
981 static void
982 ApPackageTooLarge (
983     const char                  *PredefinedName,
984     ACPI_PARSE_OBJECT           *Op,
985     UINT32                      Count,
986     UINT32                      ExpectedCount)
987 {
988 
989     sprintf (AslGbl_MsgBuffer, "%4.4s: length is %u, only %u required",
990         PredefinedName, Count, ExpectedCount);
991 
992     AslError (ASL_REMARK, ASL_MSG_RESERVED_PACKAGE_LENGTH, Op, AslGbl_MsgBuffer);
993 }
994