1 /******************************************************************************
2  *
3  * Module Name: aslprepkg - support for ACPI predefined name package objects
4  *
5  *****************************************************************************/
6 
7 /*
8  * Copyright (C) 2000 - 2022, 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 MERCHANTABILITY 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 ACPI_PARSE_OBJECT *
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 static void
92 ApCustomPackage (
93     ACPI_PARSE_OBJECT           *ParentOp,
94     const ACPI_PREDEFINED_INFO  *Predefined);
95 
96 
97 /*******************************************************************************
98  *
99  * FUNCTION:    ApCheckPackage
100  *
101  * PARAMETERS:  ParentOp            - Parser op for the package
102  *              Predefined          - Pointer to package-specific info for
103  *                                    the method
104  *
105  * RETURN:      None
106  *
107  * DESCRIPTION: Top-level validation for predefined name return package
108  *              objects.
109  *
110  ******************************************************************************/
111 
112 void
ApCheckPackage(ACPI_PARSE_OBJECT * ParentOp,const ACPI_PREDEFINED_INFO * Predefined)113 ApCheckPackage (
114     ACPI_PARSE_OBJECT           *ParentOp,
115     const ACPI_PREDEFINED_INFO  *Predefined)
116 {
117     ACPI_PARSE_OBJECT           *Op;
118     const ACPI_PREDEFINED_INFO  *Package;
119     ACPI_STATUS                 Status;
120     UINT32                      ExpectedCount;
121     UINT32                      Count;
122     UINT32                      i;
123 
124 
125     /* The package info for this name is in the next table entry */
126 
127     Package = Predefined + 1;
128 
129     /* First child is the package length */
130 
131     Op = ParentOp->Asl.Child;
132     Count = (UINT32) Op->Asl.Value.Integer;
133 
134     /*
135      * Many of the variable-length top-level packages are allowed to simply
136      * have zero elements. This allows the BIOS to tell the host that even
137      * though the predefined name/method exists, the feature is not supported.
138      * Other package types require one or more elements. In any case, there
139      * is no need to continue validation.
140      */
141     if (!Count)
142     {
143         switch (Package->RetInfo.Type)
144         {
145         case ACPI_PTYPE1_FIXED:
146         case ACPI_PTYPE1_OPTION:
147         case ACPI_PTYPE2_PKG_COUNT:
148         case ACPI_PTYPE2_REV_FIXED:
149 
150             ApZeroLengthPackage (Predefined->Info.Name, ParentOp);
151             break;
152 
153         case ACPI_PTYPE1_VAR:
154         case ACPI_PTYPE2:
155         case ACPI_PTYPE2_COUNT:
156         case ACPI_PTYPE2_FIXED:
157         case ACPI_PTYPE2_MIN:
158         case ACPI_PTYPE2_FIX_VAR:
159         case ACPI_PTYPE2_VAR_VAR:
160         default:
161 
162             break;
163         }
164 
165         return;
166     }
167 
168     /* Get the first element of the package */
169 
170     Op = Op->Asl.Next;
171 
172     /* Decode the package type */
173 
174     switch (Package->RetInfo.Type)
175     {
176     case ACPI_PTYPE_CUSTOM:
177 
178         ApCustomPackage (ParentOp, Predefined);
179         break;
180 
181     case ACPI_PTYPE1_FIXED:
182         /*
183          * The package count is fixed and there are no subpackages
184          *
185          * If package is too small, exit.
186          * If package is larger than expected, issue warning but continue
187          */
188         ExpectedCount = Package->RetInfo.Count1 + Package->RetInfo.Count2;
189         if (Count < ExpectedCount)
190         {
191             goto PackageTooSmall;
192         }
193         else if (Count > ExpectedCount)
194         {
195             ApPackageTooLarge (Predefined->Info.Name, ParentOp,
196                 Count, ExpectedCount);
197         }
198 
199         /* Validate all elements of the package */
200 
201         ApCheckPackageElements (Predefined->Info.Name, Op,
202             Package->RetInfo.ObjectType1, Package->RetInfo.Count1,
203             Package->RetInfo.ObjectType2, Package->RetInfo.Count2);
204         break;
205 
206     case ACPI_PTYPE1_VAR:
207         /*
208          * The package count is variable, there are no subpackages,
209          * and all elements must be of the same type
210          */
211         for (i = 0; i < Count; i++)
212         {
213             if (!Op)
214             {
215                 /*
216                  * If we get to this point, it means that the package length
217                  * is larger than the initializer list. Stop processing the
218                  * package and return because we have run out of package
219                  * elements to analyze.
220                  */
221                 return;
222             }
223 
224             ApCheckObjectType (Predefined->Info.Name, Op,
225                 Package->RetInfo.ObjectType1, i);
226             Op = Op->Asl.Next;
227         }
228         break;
229 
230     case ACPI_PTYPE1_OPTION:
231         /*
232          * The package count is variable, there are no subpackages.
233          * There are a fixed number of required elements, and a variable
234          * number of optional elements.
235          *
236          * Check if package is at least as large as the minimum required
237          */
238         ExpectedCount = Package->RetInfo3.Count;
239         if (Count < ExpectedCount)
240         {
241             goto PackageTooSmall;
242         }
243 
244         /* Variable number of sub-objects */
245 
246         for (i = 0; i < Count; i++)
247         {
248             if (i < Package->RetInfo3.Count)
249             {
250                 /* These are the required package elements (0, 1, or 2) */
251 
252                 ApCheckObjectType (Predefined->Info.Name, Op,
253                     Package->RetInfo3.ObjectType[i], i);
254             }
255             else
256             {
257                 /* These are the optional package elements */
258 
259                 ApCheckObjectType (Predefined->Info.Name, Op,
260                     Package->RetInfo3.TailObjectType, i);
261             }
262 
263             Op = Op->Asl.Next;
264         }
265         break;
266 
267     case ACPI_PTYPE2_REV_FIXED:
268 
269         /* First element is the (Integer) revision */
270 
271         ApCheckObjectType (Predefined->Info.Name, Op,
272             ACPI_RTYPE_INTEGER, 0);
273 
274         Op = Op->Asl.Next;
275         Count--;
276 
277         /* Examine the subpackages */
278 
279         ApCheckPackageList (Predefined->Info.Name, Op,
280             Package, 1, Count);
281         break;
282 
283     case ACPI_PTYPE2_PKG_COUNT:
284 
285         /* First element is the (Integer) count of subpackages to follow */
286 
287         Status = ApCheckObjectType (Predefined->Info.Name, Op,
288             ACPI_RTYPE_INTEGER, 0);
289 
290         /* We must have an integer count from above (otherwise, use Count) */
291 
292         if (ACPI_SUCCESS (Status))
293         {
294             /*
295              * Count cannot be larger than the parent package length, but
296              * allow it to be smaller. The >= accounts for the Integer above.
297              */
298             ExpectedCount = (UINT32) Op->Asl.Value.Integer;
299             if (ExpectedCount >= Count)
300             {
301                 goto PackageTooSmall;
302             }
303 
304             Count = ExpectedCount;
305         }
306 
307         Op = Op->Asl.Next;
308 
309         /* Examine the subpackages */
310 
311         ApCheckPackageList (Predefined->Info.Name, Op,
312             Package, 1, Count);
313         break;
314 
315     case ACPI_PTYPE2_UUID_PAIR:
316 
317         /* The package contains a variable list of UUID Buffer/Package pairs */
318 
319         /* The length of the package must be even */
320 
321         if (Count & 1)
322         {
323             sprintf (AslGbl_MsgBuffer, "%4.4s: Package length, %d, must be even.",
324                 Predefined->Info.Name, Count);
325 
326             AslError (ASL_ERROR, ASL_MSG_RESERVED_PACKAGE_LENGTH,
327                 ParentOp->Asl.Child, AslGbl_MsgBuffer);
328         }
329 
330         /* Validate the alternating types */
331 
332         for (i = 0; i < Count; ++i)
333         {
334             if (i & 1)
335             {
336                 ApCheckObjectType (Predefined->Info.Name, Op,
337                     Package->RetInfo.ObjectType2, i);
338             }
339             else
340             {
341                 ApCheckObjectType (Predefined->Info.Name, Op,
342                     Package->RetInfo.ObjectType1, i);
343             }
344 
345             Op = Op->Asl.Next;
346         }
347 
348         break;
349 
350     case ACPI_PTYPE2_VAR_VAR:
351 
352         /* Check for minimum size (ints at beginning + 1 subpackage) */
353 
354         ExpectedCount = Package->RetInfo4.Count1 + 1;
355         if (Count < ExpectedCount)
356         {
357             goto PackageTooSmall;
358         }
359 
360         /* Check the non-package elements at beginning of main package */
361 
362         for (i = 0; i < Package->RetInfo4.Count1; ++i)
363         {
364             ApCheckObjectType (Predefined->Info.Name, Op,
365                 Package->RetInfo4.ObjectType1, i);
366             Op = Op->Asl.Next;
367         }
368 
369         /* Examine the variable-length list of subpackages */
370 
371         ApCheckPackageList (Predefined->Info.Name, Op,
372             Package, Package->RetInfo4.Count1, Count);
373 
374         break;
375 
376     case ACPI_PTYPE2:
377     case ACPI_PTYPE2_FIXED:
378     case ACPI_PTYPE2_MIN:
379     case ACPI_PTYPE2_COUNT:
380     case ACPI_PTYPE2_FIX_VAR:
381         /*
382          * These types all return a single Package that consists of a
383          * variable number of subpackages.
384          */
385 
386         /* Examine the subpackages */
387 
388         ApCheckPackageList (Predefined->Info.Name, Op,
389             Package, 0, Count);
390         break;
391 
392     default:
393         return;
394     }
395 
396     return;
397 
398 PackageTooSmall:
399     ApPackageTooSmall (Predefined->Info.Name, ParentOp,
400         Count, ExpectedCount);
401 }
402 
403 
404 /*******************************************************************************
405  *
406  * FUNCTION:    ApCustomPackage
407  *
408  * PARAMETERS:  ParentOp            - Parse op for the package
409  *              Predefined          - Pointer to package-specific info for
410  *                                    the method
411  *
412  * RETURN:      None
413  *
414  * DESCRIPTION: Validate packages that don't fit into the standard model and
415  *              require custom code.
416  *
417  * NOTE: Currently used for the _BIX method only. When needed for two or more
418  * methods, probably a detect/dispatch mechanism will be required.
419  *
420  ******************************************************************************/
421 
422 static void
ApCustomPackage(ACPI_PARSE_OBJECT * ParentOp,const ACPI_PREDEFINED_INFO * Predefined)423 ApCustomPackage (
424     ACPI_PARSE_OBJECT           *ParentOp,
425     const ACPI_PREDEFINED_INFO  *Predefined)
426 {
427     ACPI_PARSE_OBJECT           *Op;
428     UINT32                      Count;
429     UINT32                      ExpectedCount;
430     UINT32                      Version;
431 
432 
433     /* First child is the package length */
434 
435     Op = ParentOp->Asl.Child;
436     Count = (UINT32) Op->Asl.Value.Integer;
437 
438     /* Get the version number, must be Integer */
439 
440     Op = Op->Asl.Next;
441     Version = (UINT32) Op->Asl.Value.Integer;
442     if (Op->Asl.ParseOpcode != PARSEOP_INTEGER)
443     {
444         AslError (ASL_ERROR, ASL_MSG_RESERVED_OPERAND_TYPE, Op, AslGbl_MsgBuffer);
445         return;
446     }
447 
448     /* Validate count (# of elements) */
449 
450     ExpectedCount = 21;         /* Version 1 */
451     if (Version == 0)
452     {
453         ExpectedCount = 20;     /* Version 0 */
454     }
455 
456     if (Count < ExpectedCount)
457     {
458         ApPackageTooSmall (Predefined->Info.Name, ParentOp,
459             Count, ExpectedCount);
460         return;
461     }
462     else if (Count > ExpectedCount)
463     {
464         ApPackageTooLarge (Predefined->Info.Name, ParentOp,
465             Count, ExpectedCount);
466     }
467 
468     /* Validate all elements of the package */
469 
470     Op = ApCheckPackageElements (Predefined->Info.Name, Op,
471         ACPI_RTYPE_INTEGER, 16,
472         ACPI_RTYPE_STRING, 4);
473 
474     /* Version 1 has a single trailing integer */
475 
476     if (Version > 0)
477     {
478         ApCheckPackageElements (Predefined->Info.Name, Op,
479             ACPI_RTYPE_INTEGER, 1, 0, 0);
480     }
481 }
482 
483 
484 /*******************************************************************************
485  *
486  * FUNCTION:    ApCheckPackageElements
487  *
488  * PARAMETERS:  PredefinedName      - Name of the predefined object
489  *              Op                  - Parser op for the package
490  *              Type1               - Object type for first group
491  *              Count1              - Count for first group
492  *              Type2               - Object type for second group
493  *              Count2              - Count for second group
494  *
495  * RETURN:      Next Op peer in the parse tree, after all specified elements
496  *              have been validated. Used for multiple validations (calls
497  *              to this function).
498  *
499  * DESCRIPTION: Validate all elements of a package. Works with packages that
500  *              are defined to contain up to two groups of different object
501  *              types.
502  *
503  ******************************************************************************/
504 
505 static ACPI_PARSE_OBJECT *
ApCheckPackageElements(const char * PredefinedName,ACPI_PARSE_OBJECT * Op,UINT8 Type1,UINT32 Count1,UINT8 Type2,UINT32 Count2)506 ApCheckPackageElements (
507     const char              *PredefinedName,
508     ACPI_PARSE_OBJECT       *Op,
509     UINT8                   Type1,
510     UINT32                  Count1,
511     UINT8                   Type2,
512     UINT32                  Count2)
513 {
514     UINT32                  i;
515 
516 
517     /*
518      * Up to two groups of package elements are supported by the data
519      * structure. All elements in each group must be of the same type.
520      * The second group can have a count of zero.
521      *
522      * Aborts check upon a NULL package element, as this means (at compile
523      * time) that the remainder of the package elements are also NULL
524      * (This is the only way to create NULL package elements.)
525      */
526     for (i = 0; (i < Count1) && Op; i++)
527     {
528         ApCheckObjectType (PredefinedName, Op, Type1, i);
529         Op = Op->Asl.Next;
530     }
531 
532     for (i = 0; (i < Count2) && Op; i++)
533     {
534         ApCheckObjectType (PredefinedName, Op, Type2, (i + Count1));
535         Op = Op->Asl.Next;
536     }
537 
538     return (Op);
539 }
540 
541 
542 /*******************************************************************************
543  *
544  * FUNCTION:    ApCheckPackageList
545  *
546  * PARAMETERS:  PredefinedName      - Name of the predefined object
547  *              ParentOp            - Parser op of the parent package
548  *              Package             - Package info for this predefined name
549  *              StartIndex          - Index in parent package where list begins
550  *              ParentCount         - Element count of parent package
551  *
552  * RETURN:      None
553  *
554  * DESCRIPTION: Validate the individual package elements for a predefined name.
555  *              Handles the cases where the predefined name is defined as a
556  *              Package of Packages (subpackages). These are the types:
557  *
558  *              ACPI_PTYPE2
559  *              ACPI_PTYPE2_FIXED
560  *              ACPI_PTYPE2_MIN
561  *              ACPI_PTYPE2_COUNT
562  *              ACPI_PTYPE2_FIX_VAR
563  *              ACPI_PTYPE2_VAR_VAR
564  *
565  ******************************************************************************/
566 
567 static void
ApCheckPackageList(const char * PredefinedName,ACPI_PARSE_OBJECT * ParentOp,const ACPI_PREDEFINED_INFO * Package,UINT32 StartIndex,UINT32 ParentCount)568 ApCheckPackageList (
569     const char                  *PredefinedName,
570     ACPI_PARSE_OBJECT           *ParentOp,
571     const ACPI_PREDEFINED_INFO  *Package,
572     UINT32                      StartIndex,
573     UINT32                      ParentCount)
574 {
575     ACPI_PARSE_OBJECT           *SubPackageOp = ParentOp;
576     ACPI_PARSE_OBJECT           *Op;
577     ACPI_STATUS                 Status;
578     UINT32                      Count;
579     UINT32                      ExpectedCount;
580     UINT32                      i;
581     UINT32                      j;
582 
583 
584     /*
585      * Validate each subpackage in the parent Package
586      *
587      * Note: We ignore NULL package elements on the assumption that
588      * they will be initialized by the BIOS or other ASL code.
589      */
590     for (i = 0; (i < ParentCount) && SubPackageOp; i++)
591     {
592         /* Each object in the list must be of type Package */
593 
594         Status = ApCheckObjectType (PredefinedName, SubPackageOp,
595             ACPI_RTYPE_PACKAGE, i + StartIndex);
596         if (ACPI_FAILURE (Status))
597         {
598             goto NextSubpackage;
599         }
600 
601         /* Examine the different types of expected subpackages */
602 
603         Op = SubPackageOp->Asl.Child;
604 
605         /* First child is the package length */
606 
607         Count = (UINT32) Op->Asl.Value.Integer;
608         Op = Op->Asl.Next;
609 
610         /*
611          * Most subpackage must have at least one element, with
612          * only rare exceptions. (_RDI)
613          */
614         if (!Count &&
615             (Package->RetInfo.Type != ACPI_PTYPE2_VAR_VAR))
616         {
617             ApZeroLengthPackage (PredefinedName, SubPackageOp);
618             goto NextSubpackage;
619         }
620 
621         /*
622          * Decode the package type.
623          * PTYPE2 indicates that a "package of packages" is expected for
624          * this name. The various flavors of PTYPE2 indicate the number
625          * and format of the subpackages.
626          */
627         switch (Package->RetInfo.Type)
628         {
629         case ACPI_PTYPE2:
630         case ACPI_PTYPE2_PKG_COUNT:
631         case ACPI_PTYPE2_REV_FIXED:
632 
633             /* Each subpackage has a fixed number of elements */
634 
635             ExpectedCount = Package->RetInfo.Count1 + Package->RetInfo.Count2;
636             if (Count < ExpectedCount)
637             {
638                 ApPackageTooSmall (PredefinedName, SubPackageOp,
639                     Count, ExpectedCount);
640                 break;
641             }
642             if (Count > ExpectedCount)
643             {
644                 ApPackageTooLarge (PredefinedName, SubPackageOp,
645                     Count, ExpectedCount);
646                 break;
647             }
648 
649             ApCheckPackageElements (PredefinedName, Op,
650                 Package->RetInfo.ObjectType1, Package->RetInfo.Count1,
651                 Package->RetInfo.ObjectType2, Package->RetInfo.Count2);
652             break;
653 
654         case ACPI_PTYPE2_FIX_VAR:
655             /*
656              * Each subpackage has a fixed number of elements and an
657              * optional element
658              */
659             ExpectedCount = Package->RetInfo.Count1 + Package->RetInfo.Count2;
660             if (Count < ExpectedCount)
661             {
662                 ApPackageTooSmall (PredefinedName, SubPackageOp,
663                     Count, ExpectedCount);
664                 break;
665             }
666 
667             ApCheckPackageElements (PredefinedName, Op,
668                 Package->RetInfo.ObjectType1, Package->RetInfo.Count1,
669                 Package->RetInfo.ObjectType2,
670                 Count - Package->RetInfo.Count1);
671             break;
672 
673         case ACPI_PTYPE2_VAR_VAR:
674             /*
675              * Must have at least the minimum number elements.
676              * A zero PkgCount means the number of elements is variable.
677              */
678             ExpectedCount = Package->RetInfo4.PkgCount;
679             if (ExpectedCount && (Count < ExpectedCount))
680             {
681                 ApPackageTooSmall (PredefinedName, SubPackageOp,
682                     Count, 1);
683                 break;
684             }
685 
686             ApCheckPackageElements (PredefinedName, Op,
687                 Package->RetInfo4.SubObjectTypes,
688                 Package->RetInfo4.PkgCount,
689                 0, 0);
690             break;
691 
692         case ACPI_PTYPE2_FIXED:
693 
694             /* Each subpackage has a fixed length */
695 
696             ExpectedCount = Package->RetInfo2.Count;
697             if (Count < ExpectedCount)
698             {
699                 ApPackageTooSmall (PredefinedName, SubPackageOp,
700                     Count, ExpectedCount);
701                 break;
702             }
703             if (Count > ExpectedCount)
704             {
705                 ApPackageTooLarge (PredefinedName, SubPackageOp,
706                     Count, ExpectedCount);
707                 break;
708             }
709 
710             /* Check each object/type combination */
711 
712             for (j = 0; j < ExpectedCount; j++)
713             {
714                 ApCheckObjectType (PredefinedName, Op,
715                     Package->RetInfo2.ObjectType[j], j);
716 
717                 Op = Op->Asl.Next;
718             }
719             break;
720 
721         case ACPI_PTYPE2_MIN:
722 
723             /* Each subpackage has a variable but minimum length */
724 
725             ExpectedCount = Package->RetInfo.Count1;
726             if (Count < ExpectedCount)
727             {
728                 ApPackageTooSmall (PredefinedName, SubPackageOp,
729                     Count, ExpectedCount);
730                 break;
731             }
732 
733             /* Check the type of each subpackage element */
734 
735             ApCheckPackageElements (PredefinedName, Op,
736                 Package->RetInfo.ObjectType1, Count, 0, 0);
737             break;
738 
739         case ACPI_PTYPE2_COUNT:
740             /*
741              * First element is the (Integer) count of elements, including
742              * the count field (the ACPI name is NumElements)
743              */
744             Status = ApCheckObjectType (PredefinedName, Op,
745                 ACPI_RTYPE_INTEGER, 0);
746 
747             /* We must have an integer count from above (otherwise, use Count) */
748 
749             if (ACPI_SUCCESS (Status))
750             {
751                 /*
752                  * Make sure package is large enough for the Count and is
753                  * is as large as the minimum size
754                  */
755                 ExpectedCount = (UINT32) Op->Asl.Value.Integer;
756 
757                 if (Count < ExpectedCount)
758                 {
759                     ApPackageTooSmall (PredefinedName, SubPackageOp,
760                         Count, ExpectedCount);
761                     break;
762                 }
763                 else if (Count > ExpectedCount)
764                 {
765                     ApPackageTooLarge (PredefinedName, SubPackageOp,
766                         Count, ExpectedCount);
767                 }
768 
769                 /* Some names of this type have a minimum length */
770 
771                 if (Count < Package->RetInfo.Count1)
772                 {
773                     ExpectedCount = Package->RetInfo.Count1;
774                     ApPackageTooSmall (PredefinedName, SubPackageOp,
775                         Count, ExpectedCount);
776                     break;
777                 }
778 
779                 Count = ExpectedCount;
780             }
781 
782             /* Check the type of each subpackage element */
783 
784             Op = Op->Asl.Next;
785             ApCheckPackageElements (PredefinedName, Op,
786                 Package->RetInfo.ObjectType1, (Count - 1), 0, 0);
787             break;
788 
789         default:
790             break;
791         }
792 
793 NextSubpackage:
794         SubPackageOp = SubPackageOp->Asl.Next;
795     }
796 }
797 
798 
799 /*******************************************************************************
800  *
801  * FUNCTION:    ApPackageTooSmall
802  *
803  * PARAMETERS:  PredefinedName      - Name of the predefined object
804  *              Op                  - Current parser op
805  *              Count               - Actual package element count
806  *              ExpectedCount       - Expected package element count
807  *
808  * RETURN:      None
809  *
810  * DESCRIPTION: Issue error message for a package that is smaller than
811  *              required.
812  *
813  ******************************************************************************/
814 
815 static void
ApPackageTooSmall(const char * PredefinedName,ACPI_PARSE_OBJECT * Op,UINT32 Count,UINT32 ExpectedCount)816 ApPackageTooSmall (
817     const char                  *PredefinedName,
818     ACPI_PARSE_OBJECT           *Op,
819     UINT32                      Count,
820     UINT32                      ExpectedCount)
821 {
822 
823     snprintf (AslGbl_MsgBuffer, sizeof(AslGbl_MsgBuffer), "%4.4s: length %u, required minimum is %u",
824         PredefinedName, Count, ExpectedCount);
825 
826     AslError (ASL_ERROR, ASL_MSG_RESERVED_PACKAGE_LENGTH, Op, AslGbl_MsgBuffer);
827 }
828 
829 
830 /*******************************************************************************
831  *
832  * FUNCTION:    ApZeroLengthPackage
833  *
834  * PARAMETERS:  PredefinedName      - Name of the predefined object
835  *              Op                  - Current parser op
836  *
837  * RETURN:      None
838  *
839  * DESCRIPTION: Issue error message for a zero-length package (a package that
840  *              is required to have a non-zero length). Variable length
841  *              packages seem to be allowed to have zero length, however.
842  *              Even if not allowed, BIOS code does it.
843  *
844  ******************************************************************************/
845 
846 static void
ApZeroLengthPackage(const char * PredefinedName,ACPI_PARSE_OBJECT * Op)847 ApZeroLengthPackage (
848     const char                  *PredefinedName,
849     ACPI_PARSE_OBJECT           *Op)
850 {
851 
852     snprintf (AslGbl_MsgBuffer, sizeof(AslGbl_MsgBuffer), "%4.4s: length is zero", PredefinedName);
853 
854     AslError (ASL_ERROR, ASL_MSG_RESERVED_PACKAGE_LENGTH, Op, AslGbl_MsgBuffer);
855 }
856 
857 
858 /*******************************************************************************
859  *
860  * FUNCTION:    ApPackageTooLarge
861  *
862  * PARAMETERS:  PredefinedName      - Name of the predefined object
863  *              Op                  - Current parser op
864  *              Count               - Actual package element count
865  *              ExpectedCount       - Expected package element count
866  *
867  * RETURN:      None
868  *
869  * DESCRIPTION: Issue a remark for a package that is larger than expected.
870  *
871  ******************************************************************************/
872 
873 static void
ApPackageTooLarge(const char * PredefinedName,ACPI_PARSE_OBJECT * Op,UINT32 Count,UINT32 ExpectedCount)874 ApPackageTooLarge (
875     const char                  *PredefinedName,
876     ACPI_PARSE_OBJECT           *Op,
877     UINT32                      Count,
878     UINT32                      ExpectedCount)
879 {
880 
881     snprintf (AslGbl_MsgBuffer, sizeof(AslGbl_MsgBuffer), "%4.4s: length is %u, only %u required",
882         PredefinedName, Count, ExpectedCount);
883 
884     AslError (ASL_REMARK, ASL_MSG_RESERVED_PACKAGE_LENGTH, Op, AslGbl_MsgBuffer);
885 }
886