xref: /freebsd/sys/contrib/dev/acpica/compiler/aslprepkg.c (revision 9c7c683c56f9d25aa7c25c40d530d7a153b19d18)
19c48c75eSJung-uk Kim /******************************************************************************
29c48c75eSJung-uk Kim  *
39c48c75eSJung-uk Kim  * Module Name: aslprepkg - support for ACPI predefined name package objects
49c48c75eSJung-uk Kim  *
59c48c75eSJung-uk Kim  *****************************************************************************/
69c48c75eSJung-uk Kim 
79c48c75eSJung-uk Kim /*
89c48c75eSJung-uk Kim  * Copyright (C) 2000 - 2013, Intel Corp.
99c48c75eSJung-uk Kim  * All rights reserved.
109c48c75eSJung-uk Kim  *
119c48c75eSJung-uk Kim  * Redistribution and use in source and binary forms, with or without
129c48c75eSJung-uk Kim  * modification, are permitted provided that the following conditions
139c48c75eSJung-uk Kim  * are met:
149c48c75eSJung-uk Kim  * 1. Redistributions of source code must retain the above copyright
159c48c75eSJung-uk Kim  *    notice, this list of conditions, and the following disclaimer,
169c48c75eSJung-uk Kim  *    without modification.
179c48c75eSJung-uk Kim  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
189c48c75eSJung-uk Kim  *    substantially similar to the "NO WARRANTY" disclaimer below
199c48c75eSJung-uk Kim  *    ("Disclaimer") and any redistribution must be conditioned upon
209c48c75eSJung-uk Kim  *    including a substantially similar Disclaimer requirement for further
219c48c75eSJung-uk Kim  *    binary redistribution.
229c48c75eSJung-uk Kim  * 3. Neither the names of the above-listed copyright holders nor the names
239c48c75eSJung-uk Kim  *    of any contributors may be used to endorse or promote products derived
249c48c75eSJung-uk Kim  *    from this software without specific prior written permission.
259c48c75eSJung-uk Kim  *
269c48c75eSJung-uk Kim  * Alternatively, this software may be distributed under the terms of the
279c48c75eSJung-uk Kim  * GNU General Public License ("GPL") version 2 as published by the Free
289c48c75eSJung-uk Kim  * Software Foundation.
299c48c75eSJung-uk Kim  *
309c48c75eSJung-uk Kim  * NO WARRANTY
319c48c75eSJung-uk Kim  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
329c48c75eSJung-uk Kim  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
339c48c75eSJung-uk Kim  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
349c48c75eSJung-uk Kim  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
359c48c75eSJung-uk Kim  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
369c48c75eSJung-uk Kim  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
379c48c75eSJung-uk Kim  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
389c48c75eSJung-uk Kim  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
399c48c75eSJung-uk Kim  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
409c48c75eSJung-uk Kim  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
419c48c75eSJung-uk Kim  * POSSIBILITY OF SUCH DAMAGES.
429c48c75eSJung-uk Kim  */
439c48c75eSJung-uk Kim 
449c48c75eSJung-uk Kim #include <contrib/dev/acpica/compiler/aslcompiler.h>
459c48c75eSJung-uk Kim #include "aslcompiler.y.h"
469c48c75eSJung-uk Kim #include <contrib/dev/acpica/include/acpredef.h>
479c48c75eSJung-uk Kim 
489c48c75eSJung-uk Kim 
499c48c75eSJung-uk Kim #define _COMPONENT          ACPI_COMPILER
509c48c75eSJung-uk Kim         ACPI_MODULE_NAME    ("aslprepkg")
519c48c75eSJung-uk Kim 
529c48c75eSJung-uk Kim 
539c48c75eSJung-uk Kim /* Local prototypes */
549c48c75eSJung-uk Kim 
559c48c75eSJung-uk Kim static void
569c48c75eSJung-uk Kim ApCheckPackageElements (
579c48c75eSJung-uk Kim     const char              *PredefinedName,
589c48c75eSJung-uk Kim     ACPI_PARSE_OBJECT       *Op,
599c48c75eSJung-uk Kim     UINT8                   Type1,
609c48c75eSJung-uk Kim     UINT32                  Count1,
619c48c75eSJung-uk Kim     UINT8                   Type2,
629c48c75eSJung-uk Kim     UINT32                  Count2);
639c48c75eSJung-uk Kim 
649c48c75eSJung-uk Kim static void
659c48c75eSJung-uk Kim ApCheckPackageList (
669c48c75eSJung-uk Kim     const char                  *PredefinedName,
679c48c75eSJung-uk Kim     ACPI_PARSE_OBJECT           *ParentOp,
689c48c75eSJung-uk Kim     const ACPI_PREDEFINED_INFO  *Package,
699c48c75eSJung-uk Kim     UINT32                      StartIndex,
709c48c75eSJung-uk Kim     UINT32                      Count);
719c48c75eSJung-uk Kim 
729c48c75eSJung-uk Kim static void
739c48c75eSJung-uk Kim ApPackageTooSmall (
749c48c75eSJung-uk Kim     const char                  *PredefinedName,
759c48c75eSJung-uk Kim     ACPI_PARSE_OBJECT           *Op,
769c48c75eSJung-uk Kim     UINT32                      Count,
779c48c75eSJung-uk Kim     UINT32                      ExpectedCount);
789c48c75eSJung-uk Kim 
799c48c75eSJung-uk Kim static void
809c48c75eSJung-uk Kim ApZeroLengthPackage (
819c48c75eSJung-uk Kim     const char                  *PredefinedName,
829c48c75eSJung-uk Kim     ACPI_PARSE_OBJECT           *Op);
839c48c75eSJung-uk Kim 
849c48c75eSJung-uk Kim static void
859c48c75eSJung-uk Kim ApPackageTooLarge (
869c48c75eSJung-uk Kim     const char                  *PredefinedName,
879c48c75eSJung-uk Kim     ACPI_PARSE_OBJECT           *Op,
889c48c75eSJung-uk Kim     UINT32                      Count,
899c48c75eSJung-uk Kim     UINT32                      ExpectedCount);
909c48c75eSJung-uk Kim 
919c48c75eSJung-uk Kim 
929c48c75eSJung-uk Kim /*******************************************************************************
939c48c75eSJung-uk Kim  *
949c48c75eSJung-uk Kim  * FUNCTION:    ApCheckPackage
959c48c75eSJung-uk Kim  *
969c48c75eSJung-uk Kim  * PARAMETERS:  ParentOp        - Parser op for the package
979c48c75eSJung-uk Kim  *              Predefined      - Pointer to package-specific info for method
989c48c75eSJung-uk Kim  *
999c48c75eSJung-uk Kim  * RETURN:      None
1009c48c75eSJung-uk Kim  *
1019c48c75eSJung-uk Kim  * DESCRIPTION: Top-level validation for predefined name return package
1029c48c75eSJung-uk Kim  *              objects.
1039c48c75eSJung-uk Kim  *
1049c48c75eSJung-uk Kim  ******************************************************************************/
1059c48c75eSJung-uk Kim 
1069c48c75eSJung-uk Kim void
1079c48c75eSJung-uk Kim ApCheckPackage (
1089c48c75eSJung-uk Kim     ACPI_PARSE_OBJECT           *ParentOp,
1099c48c75eSJung-uk Kim     const ACPI_PREDEFINED_INFO  *Predefined)
1109c48c75eSJung-uk Kim {
1119c48c75eSJung-uk Kim     ACPI_PARSE_OBJECT           *Op;
1129c48c75eSJung-uk Kim     const ACPI_PREDEFINED_INFO  *Package;
1139c48c75eSJung-uk Kim     ACPI_STATUS                 Status;
1149c48c75eSJung-uk Kim     UINT32                      ExpectedCount;
1159c48c75eSJung-uk Kim     UINT32                      Count;
1169c48c75eSJung-uk Kim     UINT32                      i;
1179c48c75eSJung-uk Kim 
1189c48c75eSJung-uk Kim 
1199c48c75eSJung-uk Kim     /* The package info for this name is in the next table entry */
1209c48c75eSJung-uk Kim 
1219c48c75eSJung-uk Kim     Package = Predefined + 1;
1229c48c75eSJung-uk Kim 
1239c48c75eSJung-uk Kim     /* First child is the package length */
1249c48c75eSJung-uk Kim 
1259c48c75eSJung-uk Kim     Op = ParentOp->Asl.Child;
1269c48c75eSJung-uk Kim     Count = (UINT32) Op->Asl.Value.Integer;
1279c48c75eSJung-uk Kim 
1289c48c75eSJung-uk Kim     /*
129*9c7c683cSJung-uk Kim      * Many of the variable-length top-level packages are allowed to simply
130*9c7c683cSJung-uk Kim      * have zero elements. This allows the BIOS to tell the host that even
131*9c7c683cSJung-uk Kim      * though the predefined name/method exists, the feature is not supported.
132*9c7c683cSJung-uk Kim      * Other package types require one or more elements. In any case, there
133*9c7c683cSJung-uk Kim      * is no need to continue validation.
1349c48c75eSJung-uk Kim      */
1359c48c75eSJung-uk Kim     if (!Count)
1369c48c75eSJung-uk Kim     {
137*9c7c683cSJung-uk Kim         switch (Package->RetInfo.Type)
1389c48c75eSJung-uk Kim         {
139*9c7c683cSJung-uk Kim         case ACPI_PTYPE1_FIXED:
140*9c7c683cSJung-uk Kim         case ACPI_PTYPE1_OPTION:
141*9c7c683cSJung-uk Kim         case ACPI_PTYPE2_PKG_COUNT:
142*9c7c683cSJung-uk Kim         case ACPI_PTYPE2_REV_FIXED:
143*9c7c683cSJung-uk Kim 
1449c48c75eSJung-uk Kim             ApZeroLengthPackage (Predefined->Info.Name, ParentOp);
145*9c7c683cSJung-uk Kim             break;
146*9c7c683cSJung-uk Kim 
147*9c7c683cSJung-uk Kim         case ACPI_PTYPE1_VAR:
148*9c7c683cSJung-uk Kim         case ACPI_PTYPE2:
149*9c7c683cSJung-uk Kim         case ACPI_PTYPE2_COUNT:
150*9c7c683cSJung-uk Kim         case ACPI_PTYPE2_FIXED:
151*9c7c683cSJung-uk Kim         case ACPI_PTYPE2_MIN:
152*9c7c683cSJung-uk Kim         case ACPI_PTYPE2_FIX_VAR:
153*9c7c683cSJung-uk Kim         default:
154*9c7c683cSJung-uk Kim 
155*9c7c683cSJung-uk Kim             break;
1569c48c75eSJung-uk Kim         }
157*9c7c683cSJung-uk Kim 
1589c48c75eSJung-uk Kim         return;
1599c48c75eSJung-uk Kim     }
1609c48c75eSJung-uk Kim 
1619c48c75eSJung-uk Kim     /* Get the first element of the package */
1629c48c75eSJung-uk Kim 
1639c48c75eSJung-uk Kim     Op = Op->Asl.Next;
1649c48c75eSJung-uk Kim 
1659c48c75eSJung-uk Kim     /* Decode the package type */
1669c48c75eSJung-uk Kim 
1679c48c75eSJung-uk Kim     switch (Package->RetInfo.Type)
1689c48c75eSJung-uk Kim     {
1699c48c75eSJung-uk Kim     case ACPI_PTYPE1_FIXED:
1709c48c75eSJung-uk Kim         /*
1719c48c75eSJung-uk Kim          * The package count is fixed and there are no sub-packages
1729c48c75eSJung-uk Kim          *
1739c48c75eSJung-uk Kim          * If package is too small, exit.
1749c48c75eSJung-uk Kim          * If package is larger than expected, issue warning but continue
1759c48c75eSJung-uk Kim          */
1769c48c75eSJung-uk Kim         ExpectedCount = Package->RetInfo.Count1 + Package->RetInfo.Count2;
1779c48c75eSJung-uk Kim         if (Count < ExpectedCount)
1789c48c75eSJung-uk Kim         {
1799c48c75eSJung-uk Kim             goto PackageTooSmall;
1809c48c75eSJung-uk Kim         }
1819c48c75eSJung-uk Kim         else if (Count > ExpectedCount)
1829c48c75eSJung-uk Kim         {
1839c48c75eSJung-uk Kim             ApPackageTooLarge (Predefined->Info.Name, ParentOp,
1849c48c75eSJung-uk Kim                 Count, ExpectedCount);
1859c48c75eSJung-uk Kim         }
1869c48c75eSJung-uk Kim 
1879c48c75eSJung-uk Kim         /* Validate all elements of the package */
1889c48c75eSJung-uk Kim 
1899c48c75eSJung-uk Kim         ApCheckPackageElements (Predefined->Info.Name, Op,
1909c48c75eSJung-uk Kim             Package->RetInfo.ObjectType1, Package->RetInfo.Count1,
1919c48c75eSJung-uk Kim             Package->RetInfo.ObjectType2, Package->RetInfo.Count2);
1929c48c75eSJung-uk Kim         break;
1939c48c75eSJung-uk Kim 
1949c48c75eSJung-uk Kim     case ACPI_PTYPE1_VAR:
1959c48c75eSJung-uk Kim         /*
1969c48c75eSJung-uk Kim          * The package count is variable, there are no sub-packages, and all
1979c48c75eSJung-uk Kim          * elements must be of the same type
1989c48c75eSJung-uk Kim          */
1999c48c75eSJung-uk Kim         for (i = 0; i < Count; i++)
2009c48c75eSJung-uk Kim         {
2019c48c75eSJung-uk Kim             ApCheckObjectType (Predefined->Info.Name, Op,
2029c48c75eSJung-uk Kim                 Package->RetInfo.ObjectType1, i);
2039c48c75eSJung-uk Kim             Op = Op->Asl.Next;
2049c48c75eSJung-uk Kim         }
2059c48c75eSJung-uk Kim         break;
2069c48c75eSJung-uk Kim 
2079c48c75eSJung-uk Kim     case ACPI_PTYPE1_OPTION:
2089c48c75eSJung-uk Kim         /*
2099c48c75eSJung-uk Kim          * The package count is variable, there are no sub-packages. There are
2109c48c75eSJung-uk Kim          * a fixed number of required elements, and a variable number of
2119c48c75eSJung-uk Kim          * optional elements.
2129c48c75eSJung-uk Kim          *
2139c48c75eSJung-uk Kim          * Check if package is at least as large as the minimum required
2149c48c75eSJung-uk Kim          */
2159c48c75eSJung-uk Kim         ExpectedCount = Package->RetInfo3.Count;
2169c48c75eSJung-uk Kim         if (Count < ExpectedCount)
2179c48c75eSJung-uk Kim         {
2189c48c75eSJung-uk Kim             goto PackageTooSmall;
2199c48c75eSJung-uk Kim         }
2209c48c75eSJung-uk Kim 
2219c48c75eSJung-uk Kim         /* Variable number of sub-objects */
2229c48c75eSJung-uk Kim 
2239c48c75eSJung-uk Kim         for (i = 0; i < Count; i++)
2249c48c75eSJung-uk Kim         {
2259c48c75eSJung-uk Kim             if (i < Package->RetInfo3.Count)
2269c48c75eSJung-uk Kim             {
2279c48c75eSJung-uk Kim                 /* These are the required package elements (0, 1, or 2) */
2289c48c75eSJung-uk Kim 
2299c48c75eSJung-uk Kim                 ApCheckObjectType (Predefined->Info.Name, Op,
2309c48c75eSJung-uk Kim                     Package->RetInfo3.ObjectType[i], i);
2319c48c75eSJung-uk Kim             }
2329c48c75eSJung-uk Kim             else
2339c48c75eSJung-uk Kim             {
2349c48c75eSJung-uk Kim                 /* These are the optional package elements */
2359c48c75eSJung-uk Kim 
2369c48c75eSJung-uk Kim                 ApCheckObjectType (Predefined->Info.Name, Op,
2379c48c75eSJung-uk Kim                     Package->RetInfo3.TailObjectType, i);
2389c48c75eSJung-uk Kim             }
2399c48c75eSJung-uk Kim             Op = Op->Asl.Next;
2409c48c75eSJung-uk Kim         }
2419c48c75eSJung-uk Kim         break;
2429c48c75eSJung-uk Kim 
2439c48c75eSJung-uk Kim     case ACPI_PTYPE2_REV_FIXED:
2449c48c75eSJung-uk Kim 
2459c48c75eSJung-uk Kim         /* First element is the (Integer) revision */
2469c48c75eSJung-uk Kim 
2479c48c75eSJung-uk Kim         ApCheckObjectType (Predefined->Info.Name, Op,
2489c48c75eSJung-uk Kim             ACPI_RTYPE_INTEGER, 0);
2499c48c75eSJung-uk Kim 
2509c48c75eSJung-uk Kim         Op = Op->Asl.Next;
2519c48c75eSJung-uk Kim         Count--;
2529c48c75eSJung-uk Kim 
2539c48c75eSJung-uk Kim         /* Examine the sub-packages */
2549c48c75eSJung-uk Kim 
2559c48c75eSJung-uk Kim         ApCheckPackageList (Predefined->Info.Name, Op,
2569c48c75eSJung-uk Kim             Package, 1, Count);
2579c48c75eSJung-uk Kim         break;
2589c48c75eSJung-uk Kim 
2599c48c75eSJung-uk Kim     case ACPI_PTYPE2_PKG_COUNT:
2609c48c75eSJung-uk Kim 
2619c48c75eSJung-uk Kim         /* First element is the (Integer) count of sub-packages to follow */
2629c48c75eSJung-uk Kim 
2639c48c75eSJung-uk Kim         Status = ApCheckObjectType (Predefined->Info.Name, Op,
2649c48c75eSJung-uk Kim             ACPI_RTYPE_INTEGER, 0);
2659c48c75eSJung-uk Kim 
2669c48c75eSJung-uk Kim         /* We must have an integer count from above (otherwise, use Count) */
2679c48c75eSJung-uk Kim 
2689c48c75eSJung-uk Kim         if (ACPI_SUCCESS (Status))
2699c48c75eSJung-uk Kim         {
2709c48c75eSJung-uk Kim             /*
2719c48c75eSJung-uk Kim              * Count cannot be larger than the parent package length, but allow it
2729c48c75eSJung-uk Kim              * to be smaller. The >= accounts for the Integer above.
2739c48c75eSJung-uk Kim              */
2749c48c75eSJung-uk Kim             ExpectedCount = (UINT32) Op->Asl.Value.Integer;
2759c48c75eSJung-uk Kim             if (ExpectedCount >= Count)
2769c48c75eSJung-uk Kim             {
2779c48c75eSJung-uk Kim                 goto PackageTooSmall;
2789c48c75eSJung-uk Kim             }
2799c48c75eSJung-uk Kim 
2809c48c75eSJung-uk Kim             Count = ExpectedCount;
2819c48c75eSJung-uk Kim         }
2829c48c75eSJung-uk Kim 
2839c48c75eSJung-uk Kim         Op = Op->Asl.Next;
2849c48c75eSJung-uk Kim 
2859c48c75eSJung-uk Kim         /* Examine the sub-packages */
2869c48c75eSJung-uk Kim 
2879c48c75eSJung-uk Kim         ApCheckPackageList (Predefined->Info.Name, Op,
2889c48c75eSJung-uk Kim             Package, 1, Count);
2899c48c75eSJung-uk Kim         break;
2909c48c75eSJung-uk Kim 
2919c48c75eSJung-uk Kim     case ACPI_PTYPE2:
2929c48c75eSJung-uk Kim     case ACPI_PTYPE2_FIXED:
2939c48c75eSJung-uk Kim     case ACPI_PTYPE2_MIN:
2949c48c75eSJung-uk Kim     case ACPI_PTYPE2_COUNT:
2959c48c75eSJung-uk Kim     case ACPI_PTYPE2_FIX_VAR:
2969c48c75eSJung-uk Kim         /*
2979c48c75eSJung-uk Kim          * These types all return a single Package that consists of a
2989c48c75eSJung-uk Kim          * variable number of sub-Packages.
2999c48c75eSJung-uk Kim          */
3009c48c75eSJung-uk Kim 
3019c48c75eSJung-uk Kim         /* Examine the sub-packages */
3029c48c75eSJung-uk Kim 
3039c48c75eSJung-uk Kim         ApCheckPackageList (Predefined->Info.Name, Op,
3049c48c75eSJung-uk Kim             Package, 0, Count);
3059c48c75eSJung-uk Kim         break;
3069c48c75eSJung-uk Kim 
3079c48c75eSJung-uk Kim     default:
3089c48c75eSJung-uk Kim         return;
3099c48c75eSJung-uk Kim     }
3109c48c75eSJung-uk Kim 
3119c48c75eSJung-uk Kim     return;
3129c48c75eSJung-uk Kim 
3139c48c75eSJung-uk Kim PackageTooSmall:
3149c48c75eSJung-uk Kim     ApPackageTooSmall (Predefined->Info.Name, ParentOp,
3159c48c75eSJung-uk Kim         Count, ExpectedCount);
3169c48c75eSJung-uk Kim }
3179c48c75eSJung-uk Kim 
3189c48c75eSJung-uk Kim 
3199c48c75eSJung-uk Kim /*******************************************************************************
3209c48c75eSJung-uk Kim  *
3219c48c75eSJung-uk Kim  * FUNCTION:    ApCheckPackageElements
3229c48c75eSJung-uk Kim  *
3239c48c75eSJung-uk Kim  * PARAMETERS:  PredefinedName  - Pointer to validation data structure
3249c48c75eSJung-uk Kim  *              Op              - Parser op for the package
3259c48c75eSJung-uk Kim  *              Type1           - Object type for first group
3269c48c75eSJung-uk Kim  *              Count1          - Count for first group
3279c48c75eSJung-uk Kim  *              Type2           - Object type for second group
3289c48c75eSJung-uk Kim  *              Count2          - Count for second group
3299c48c75eSJung-uk Kim  *
3309c48c75eSJung-uk Kim  * RETURN:      None
3319c48c75eSJung-uk Kim  *
3329c48c75eSJung-uk Kim  * DESCRIPTION: Validate all elements of a package. Works with packages that
3339c48c75eSJung-uk Kim  *              are defined to contain up to two groups of different object
3349c48c75eSJung-uk Kim  *              types.
3359c48c75eSJung-uk Kim  *
3369c48c75eSJung-uk Kim  ******************************************************************************/
3379c48c75eSJung-uk Kim 
3389c48c75eSJung-uk Kim static void
3399c48c75eSJung-uk Kim ApCheckPackageElements (
3409c48c75eSJung-uk Kim     const char              *PredefinedName,
3419c48c75eSJung-uk Kim     ACPI_PARSE_OBJECT       *Op,
3429c48c75eSJung-uk Kim     UINT8                   Type1,
3439c48c75eSJung-uk Kim     UINT32                  Count1,
3449c48c75eSJung-uk Kim     UINT8                   Type2,
3459c48c75eSJung-uk Kim     UINT32                  Count2)
3469c48c75eSJung-uk Kim {
3479c48c75eSJung-uk Kim     UINT32                  i;
3489c48c75eSJung-uk Kim 
3499c48c75eSJung-uk Kim 
3509c48c75eSJung-uk Kim     /*
3519c48c75eSJung-uk Kim      * Up to two groups of package elements are supported by the data
3529c48c75eSJung-uk Kim      * structure. All elements in each group must be of the same type.
3539c48c75eSJung-uk Kim      * The second group can have a count of zero.
3549c48c75eSJung-uk Kim      *
3559c48c75eSJung-uk Kim      * Aborts check upon a NULL package element, as this means (at compile
3569c48c75eSJung-uk Kim      * time) that the remainder of the package elements are also NULL
3579c48c75eSJung-uk Kim      * (This is the only way to create NULL package elements.)
3589c48c75eSJung-uk Kim      */
3599c48c75eSJung-uk Kim     for (i = 0; (i < Count1) && Op; i++)
3609c48c75eSJung-uk Kim     {
3619c48c75eSJung-uk Kim         ApCheckObjectType (PredefinedName, Op, Type1, i);
3629c48c75eSJung-uk Kim         Op = Op->Asl.Next;
3639c48c75eSJung-uk Kim     }
3649c48c75eSJung-uk Kim 
3659c48c75eSJung-uk Kim     for (i = 0; (i < Count2) && Op; i++)
3669c48c75eSJung-uk Kim     {
3679c48c75eSJung-uk Kim         ApCheckObjectType (PredefinedName, Op, Type2, (i + Count1));
3689c48c75eSJung-uk Kim         Op = Op->Asl.Next;
3699c48c75eSJung-uk Kim     }
3709c48c75eSJung-uk Kim }
3719c48c75eSJung-uk Kim 
3729c48c75eSJung-uk Kim 
3739c48c75eSJung-uk Kim /*******************************************************************************
3749c48c75eSJung-uk Kim  *
3759c48c75eSJung-uk Kim  * FUNCTION:    ApCheckPackageList
3769c48c75eSJung-uk Kim  *
3779c48c75eSJung-uk Kim  * PARAMETERS:  PredefinedName      - Name of the predefined object
3789c48c75eSJung-uk Kim  *              ParentOp            - Parser op of the parent package
3799c48c75eSJung-uk Kim  *              Package             - Package info for this predefined name
3809c48c75eSJung-uk Kim  *              StartIndex          - Index in parent package where list begins
3819c48c75eSJung-uk Kim  *              ParentCount         - Element count of parent package
3829c48c75eSJung-uk Kim  *
3839c48c75eSJung-uk Kim  * RETURN:      None
3849c48c75eSJung-uk Kim  *
3859c48c75eSJung-uk Kim  * DESCRIPTION: Validate the individual package elements for a predefined name.
3869c48c75eSJung-uk Kim  *              Handles the cases where the predefined name is defined as a
3879c48c75eSJung-uk Kim  *              Package of Packages (subpackages). These are the types:
3889c48c75eSJung-uk Kim  *
3899c48c75eSJung-uk Kim  *              ACPI_PTYPE2
3909c48c75eSJung-uk Kim  *              ACPI_PTYPE2_FIXED
3919c48c75eSJung-uk Kim  *              ACPI_PTYPE2_MIN
3929c48c75eSJung-uk Kim  *              ACPI_PTYPE2_COUNT
3939c48c75eSJung-uk Kim  *              ACPI_PTYPE2_FIX_VAR
3949c48c75eSJung-uk Kim  *
3959c48c75eSJung-uk Kim  ******************************************************************************/
3969c48c75eSJung-uk Kim 
3979c48c75eSJung-uk Kim static void
3989c48c75eSJung-uk Kim ApCheckPackageList (
3999c48c75eSJung-uk Kim     const char                  *PredefinedName,
4009c48c75eSJung-uk Kim     ACPI_PARSE_OBJECT           *ParentOp,
4019c48c75eSJung-uk Kim     const ACPI_PREDEFINED_INFO  *Package,
4029c48c75eSJung-uk Kim     UINT32                      StartIndex,
4039c48c75eSJung-uk Kim     UINT32                      ParentCount)
4049c48c75eSJung-uk Kim {
4059c48c75eSJung-uk Kim     ACPI_PARSE_OBJECT           *SubPackageOp = ParentOp;
4069c48c75eSJung-uk Kim     ACPI_PARSE_OBJECT           *Op;
4079c48c75eSJung-uk Kim     ACPI_STATUS                 Status;
4089c48c75eSJung-uk Kim     UINT32                      Count;
4099c48c75eSJung-uk Kim     UINT32                      ExpectedCount;
4109c48c75eSJung-uk Kim     UINT32                      i;
4119c48c75eSJung-uk Kim     UINT32                      j;
4129c48c75eSJung-uk Kim 
4139c48c75eSJung-uk Kim 
4149c48c75eSJung-uk Kim     /*
4159c48c75eSJung-uk Kim      * Validate each subpackage in the parent Package
4169c48c75eSJung-uk Kim      *
4179c48c75eSJung-uk Kim      * Note: We ignore NULL package elements on the assumption that
4189c48c75eSJung-uk Kim      * they will be initialized by the BIOS or other ASL code.
4199c48c75eSJung-uk Kim      */
4209c48c75eSJung-uk Kim     for (i = 0; (i < ParentCount) && SubPackageOp; i++)
4219c48c75eSJung-uk Kim     {
4229c48c75eSJung-uk Kim         /* Each object in the list must be of type Package */
4239c48c75eSJung-uk Kim 
4249c48c75eSJung-uk Kim         Status = ApCheckObjectType (PredefinedName, SubPackageOp,
4259c48c75eSJung-uk Kim             ACPI_RTYPE_PACKAGE, i + StartIndex);
4269c48c75eSJung-uk Kim         if (ACPI_FAILURE (Status))
4279c48c75eSJung-uk Kim         {
4289c48c75eSJung-uk Kim             goto NextSubpackage;
4299c48c75eSJung-uk Kim         }
4309c48c75eSJung-uk Kim 
4319c48c75eSJung-uk Kim         /* Examine the different types of expected subpackages */
4329c48c75eSJung-uk Kim 
4339c48c75eSJung-uk Kim         Op = SubPackageOp->Asl.Child;
4349c48c75eSJung-uk Kim 
4359c48c75eSJung-uk Kim         /* First child is the package length */
4369c48c75eSJung-uk Kim 
4379c48c75eSJung-uk Kim         Count = (UINT32) Op->Asl.Value.Integer;
4389c48c75eSJung-uk Kim         Op = Op->Asl.Next;
4399c48c75eSJung-uk Kim 
4409c48c75eSJung-uk Kim         /* The subpackage must have at least one element */
4419c48c75eSJung-uk Kim 
4429c48c75eSJung-uk Kim         if (!Count)
4439c48c75eSJung-uk Kim         {
4449c48c75eSJung-uk Kim             ApZeroLengthPackage (PredefinedName, SubPackageOp);
4459c48c75eSJung-uk Kim             goto NextSubpackage;
4469c48c75eSJung-uk Kim         }
4479c48c75eSJung-uk Kim 
4489c48c75eSJung-uk Kim         /*
4499c48c75eSJung-uk Kim          * Decode the package type.
4509c48c75eSJung-uk Kim          * PTYPE2 indicates that a "package of packages" is expected for
4519c48c75eSJung-uk Kim          * this name. The various flavors of PTYPE2 indicate the number
4529c48c75eSJung-uk Kim          * and format of the subpackages.
4539c48c75eSJung-uk Kim          */
4549c48c75eSJung-uk Kim         switch (Package->RetInfo.Type)
4559c48c75eSJung-uk Kim         {
4569c48c75eSJung-uk Kim         case ACPI_PTYPE2:
4579c48c75eSJung-uk Kim         case ACPI_PTYPE2_PKG_COUNT:
4589c48c75eSJung-uk Kim         case ACPI_PTYPE2_REV_FIXED:
4599c48c75eSJung-uk Kim 
4609c48c75eSJung-uk Kim             /* Each subpackage has a fixed number of elements */
4619c48c75eSJung-uk Kim 
4629c48c75eSJung-uk Kim             ExpectedCount = Package->RetInfo.Count1 + Package->RetInfo.Count2;
4639c48c75eSJung-uk Kim             if (Count < ExpectedCount)
4649c48c75eSJung-uk Kim             {
4659c48c75eSJung-uk Kim                 ApPackageTooSmall (PredefinedName, SubPackageOp,
4669c48c75eSJung-uk Kim                     Count, ExpectedCount);
4679c48c75eSJung-uk Kim                 break;
4689c48c75eSJung-uk Kim             }
4699c48c75eSJung-uk Kim 
4709c48c75eSJung-uk Kim             ApCheckPackageElements (PredefinedName, Op,
4719c48c75eSJung-uk Kim                 Package->RetInfo.ObjectType1, Package->RetInfo.Count1,
4729c48c75eSJung-uk Kim                 Package->RetInfo.ObjectType2, Package->RetInfo.Count2);
4739c48c75eSJung-uk Kim             break;
4749c48c75eSJung-uk Kim 
4759c48c75eSJung-uk Kim         case ACPI_PTYPE2_FIX_VAR:
4769c48c75eSJung-uk Kim             /*
4779c48c75eSJung-uk Kim              * Each subpackage has a fixed number of elements and an
4789c48c75eSJung-uk Kim              * optional element
4799c48c75eSJung-uk Kim              */
4809c48c75eSJung-uk Kim             ExpectedCount = Package->RetInfo.Count1 + Package->RetInfo.Count2;
4819c48c75eSJung-uk Kim             if (Count < ExpectedCount)
4829c48c75eSJung-uk Kim             {
4839c48c75eSJung-uk Kim                 ApPackageTooSmall (PredefinedName, SubPackageOp,
4849c48c75eSJung-uk Kim                     Count, ExpectedCount);
4859c48c75eSJung-uk Kim                 break;
4869c48c75eSJung-uk Kim             }
4879c48c75eSJung-uk Kim 
4889c48c75eSJung-uk Kim             ApCheckPackageElements (PredefinedName, Op,
4899c48c75eSJung-uk Kim                 Package->RetInfo.ObjectType1, Package->RetInfo.Count1,
4909c48c75eSJung-uk Kim                 Package->RetInfo.ObjectType2,
4919c48c75eSJung-uk Kim                 Count - Package->RetInfo.Count1);
4929c48c75eSJung-uk Kim             break;
4939c48c75eSJung-uk Kim 
4949c48c75eSJung-uk Kim         case ACPI_PTYPE2_FIXED:
4959c48c75eSJung-uk Kim 
4969c48c75eSJung-uk Kim             /* Each sub-package has a fixed length */
4979c48c75eSJung-uk Kim 
4989c48c75eSJung-uk Kim             ExpectedCount = Package->RetInfo2.Count;
4999c48c75eSJung-uk Kim             if (Count < ExpectedCount)
5009c48c75eSJung-uk Kim             {
5019c48c75eSJung-uk Kim                 ApPackageTooSmall (PredefinedName, SubPackageOp,
5029c48c75eSJung-uk Kim                     Count, ExpectedCount);
5039c48c75eSJung-uk Kim                 break;
5049c48c75eSJung-uk Kim             }
5059c48c75eSJung-uk Kim 
5069c48c75eSJung-uk Kim             /* Check each object/type combination */
5079c48c75eSJung-uk Kim 
5089c48c75eSJung-uk Kim             for (j = 0; j < ExpectedCount; j++)
5099c48c75eSJung-uk Kim             {
5109c48c75eSJung-uk Kim                 ApCheckObjectType (PredefinedName, Op,
5119c48c75eSJung-uk Kim                     Package->RetInfo2.ObjectType[j], j);
5129c48c75eSJung-uk Kim 
5139c48c75eSJung-uk Kim                 Op = Op->Asl.Next;
5149c48c75eSJung-uk Kim             }
5159c48c75eSJung-uk Kim             break;
5169c48c75eSJung-uk Kim 
5179c48c75eSJung-uk Kim         case ACPI_PTYPE2_MIN:
5189c48c75eSJung-uk Kim 
5199c48c75eSJung-uk Kim             /* Each sub-package has a variable but minimum length */
5209c48c75eSJung-uk Kim 
5219c48c75eSJung-uk Kim             ExpectedCount = Package->RetInfo.Count1;
5229c48c75eSJung-uk Kim             if (Count < ExpectedCount)
5239c48c75eSJung-uk Kim             {
5249c48c75eSJung-uk Kim                 ApPackageTooSmall (PredefinedName, SubPackageOp,
5259c48c75eSJung-uk Kim                     Count, ExpectedCount);
5269c48c75eSJung-uk Kim                 break;
5279c48c75eSJung-uk Kim             }
5289c48c75eSJung-uk Kim 
5299c48c75eSJung-uk Kim             /* Check the type of each sub-package element */
5309c48c75eSJung-uk Kim 
5319c48c75eSJung-uk Kim             ApCheckPackageElements (PredefinedName, Op,
5329c48c75eSJung-uk Kim                 Package->RetInfo.ObjectType1, Count, 0, 0);
5339c48c75eSJung-uk Kim             break;
5349c48c75eSJung-uk Kim 
5359c48c75eSJung-uk Kim         case ACPI_PTYPE2_COUNT:
5369c48c75eSJung-uk Kim             /*
5379c48c75eSJung-uk Kim              * First element is the (Integer) count of elements, including
5389c48c75eSJung-uk Kim              * the count field (the ACPI name is NumElements)
5399c48c75eSJung-uk Kim              */
5409c48c75eSJung-uk Kim             Status = ApCheckObjectType (PredefinedName, Op,
5419c48c75eSJung-uk Kim                 ACPI_RTYPE_INTEGER, 0);
5429c48c75eSJung-uk Kim 
5439c48c75eSJung-uk Kim             /* We must have an integer count from above (otherwise, use Count) */
5449c48c75eSJung-uk Kim 
5459c48c75eSJung-uk Kim             if (ACPI_SUCCESS (Status))
5469c48c75eSJung-uk Kim             {
5479c48c75eSJung-uk Kim                 /*
5489c48c75eSJung-uk Kim                  * Make sure package is large enough for the Count and is
5499c48c75eSJung-uk Kim                  * is as large as the minimum size
5509c48c75eSJung-uk Kim                  */
5519c48c75eSJung-uk Kim                 ExpectedCount = (UINT32) Op->Asl.Value.Integer;
5529c48c75eSJung-uk Kim 
5539c48c75eSJung-uk Kim                 if (Count < ExpectedCount)
5549c48c75eSJung-uk Kim                 {
5559c48c75eSJung-uk Kim                     ApPackageTooSmall (PredefinedName, SubPackageOp,
5569c48c75eSJung-uk Kim                         Count, ExpectedCount);
5579c48c75eSJung-uk Kim                     break;
5589c48c75eSJung-uk Kim                 }
5599c48c75eSJung-uk Kim                 else if (Count > ExpectedCount)
5609c48c75eSJung-uk Kim                 {
5619c48c75eSJung-uk Kim                     ApPackageTooLarge (PredefinedName, SubPackageOp,
5629c48c75eSJung-uk Kim                         Count, ExpectedCount);
5639c48c75eSJung-uk Kim                 }
5649c48c75eSJung-uk Kim 
5659c48c75eSJung-uk Kim                 /* Some names of this type have a minimum length */
5669c48c75eSJung-uk Kim 
5679c48c75eSJung-uk Kim                 if (Count < Package->RetInfo.Count1)
5689c48c75eSJung-uk Kim                 {
5699c48c75eSJung-uk Kim                     ExpectedCount = Package->RetInfo.Count1;
5709c48c75eSJung-uk Kim                     ApPackageTooSmall (PredefinedName, SubPackageOp,
5719c48c75eSJung-uk Kim                         Count, ExpectedCount);
5729c48c75eSJung-uk Kim                     break;
5739c48c75eSJung-uk Kim                 }
5749c48c75eSJung-uk Kim 
5759c48c75eSJung-uk Kim                 Count = ExpectedCount;
5769c48c75eSJung-uk Kim             }
5779c48c75eSJung-uk Kim 
5789c48c75eSJung-uk Kim             /* Check the type of each sub-package element */
5799c48c75eSJung-uk Kim 
5809c48c75eSJung-uk Kim             Op = Op->Asl.Next;
5819c48c75eSJung-uk Kim             ApCheckPackageElements (PredefinedName, Op,
5829c48c75eSJung-uk Kim                 Package->RetInfo.ObjectType1, (Count - 1), 0, 0);
5839c48c75eSJung-uk Kim             break;
5849c48c75eSJung-uk Kim 
5859c48c75eSJung-uk Kim         default:
5869c48c75eSJung-uk Kim             break;
5879c48c75eSJung-uk Kim         }
5889c48c75eSJung-uk Kim 
5899c48c75eSJung-uk Kim NextSubpackage:
5909c48c75eSJung-uk Kim         SubPackageOp = SubPackageOp->Asl.Next;
5919c48c75eSJung-uk Kim     }
5929c48c75eSJung-uk Kim }
5939c48c75eSJung-uk Kim 
5949c48c75eSJung-uk Kim 
5959c48c75eSJung-uk Kim /*******************************************************************************
5969c48c75eSJung-uk Kim  *
5979c48c75eSJung-uk Kim  * FUNCTION:    ApPackageTooSmall
5989c48c75eSJung-uk Kim  *
5999c48c75eSJung-uk Kim  * PARAMETERS:  PredefinedName      - Name of the predefined object
6009c48c75eSJung-uk Kim  *              Op                  - Current parser op
6019c48c75eSJung-uk Kim  *              Count               - Actual package element count
6029c48c75eSJung-uk Kim  *              ExpectedCount       - Expected package element count
6039c48c75eSJung-uk Kim  *
6049c48c75eSJung-uk Kim  * RETURN:      None
6059c48c75eSJung-uk Kim  *
6069c48c75eSJung-uk Kim  * DESCRIPTION: Issue error message for a package that is smaller than
6079c48c75eSJung-uk Kim  *              required.
6089c48c75eSJung-uk Kim  *
6099c48c75eSJung-uk Kim  ******************************************************************************/
6109c48c75eSJung-uk Kim 
6119c48c75eSJung-uk Kim static void
6129c48c75eSJung-uk Kim ApPackageTooSmall (
6139c48c75eSJung-uk Kim     const char                  *PredefinedName,
6149c48c75eSJung-uk Kim     ACPI_PARSE_OBJECT           *Op,
6159c48c75eSJung-uk Kim     UINT32                      Count,
6169c48c75eSJung-uk Kim     UINT32                      ExpectedCount)
6179c48c75eSJung-uk Kim {
6189c48c75eSJung-uk Kim 
6199c48c75eSJung-uk Kim     sprintf (MsgBuffer, "%s: length %u, required minimum is %u",
6209c48c75eSJung-uk Kim         PredefinedName, Count, ExpectedCount);
6219c48c75eSJung-uk Kim 
6229c48c75eSJung-uk Kim     AslError (ASL_ERROR, ASL_MSG_RESERVED_PACKAGE_LENGTH, Op, MsgBuffer);
6239c48c75eSJung-uk Kim }
6249c48c75eSJung-uk Kim 
6259c48c75eSJung-uk Kim 
6269c48c75eSJung-uk Kim /*******************************************************************************
6279c48c75eSJung-uk Kim  *
6289c48c75eSJung-uk Kim  * FUNCTION:    ApZeroLengthPackage
6299c48c75eSJung-uk Kim  *
6309c48c75eSJung-uk Kim  * PARAMETERS:  PredefinedName      - Name of the predefined object
6319c48c75eSJung-uk Kim  *              Op                  - Current parser op
6329c48c75eSJung-uk Kim  *
6339c48c75eSJung-uk Kim  * RETURN:      None
6349c48c75eSJung-uk Kim  *
6359c48c75eSJung-uk Kim  * DESCRIPTION: Issue error message for a zero-length package (a package that
6369c48c75eSJung-uk Kim  *              is required to have a non-zero length). Variable length
6379c48c75eSJung-uk Kim  *              packages seem to be allowed to have zero length, however.
6389c48c75eSJung-uk Kim  *              Even if not allowed, BIOS code does it.
6399c48c75eSJung-uk Kim  *
6409c48c75eSJung-uk Kim  ******************************************************************************/
6419c48c75eSJung-uk Kim 
6429c48c75eSJung-uk Kim static void
6439c48c75eSJung-uk Kim ApZeroLengthPackage (
6449c48c75eSJung-uk Kim     const char                  *PredefinedName,
6459c48c75eSJung-uk Kim     ACPI_PARSE_OBJECT           *Op)
6469c48c75eSJung-uk Kim {
6479c48c75eSJung-uk Kim 
6489c48c75eSJung-uk Kim     sprintf (MsgBuffer, "%s: length is zero", PredefinedName);
6499c48c75eSJung-uk Kim 
6509c48c75eSJung-uk Kim     AslError (ASL_ERROR, ASL_MSG_RESERVED_PACKAGE_LENGTH, Op, MsgBuffer);
6519c48c75eSJung-uk Kim }
6529c48c75eSJung-uk Kim 
6539c48c75eSJung-uk Kim 
6549c48c75eSJung-uk Kim /*******************************************************************************
6559c48c75eSJung-uk Kim  *
6569c48c75eSJung-uk Kim  * FUNCTION:    ApPackageTooLarge
6579c48c75eSJung-uk Kim  *
6589c48c75eSJung-uk Kim  * PARAMETERS:  PredefinedName      - Name of the predefined object
6599c48c75eSJung-uk Kim  *              Op                  - Current parser op
6609c48c75eSJung-uk Kim  *              Count               - Actual package element count
6619c48c75eSJung-uk Kim  *              ExpectedCount       - Expected package element count
6629c48c75eSJung-uk Kim  *
6639c48c75eSJung-uk Kim  * RETURN:      None
6649c48c75eSJung-uk Kim  *
6659c48c75eSJung-uk Kim  * DESCRIPTION: Issue a remark for a package that is larger than expected.
6669c48c75eSJung-uk Kim  *
6679c48c75eSJung-uk Kim  ******************************************************************************/
6689c48c75eSJung-uk Kim 
6699c48c75eSJung-uk Kim static void
6709c48c75eSJung-uk Kim ApPackageTooLarge (
6719c48c75eSJung-uk Kim     const char                  *PredefinedName,
6729c48c75eSJung-uk Kim     ACPI_PARSE_OBJECT           *Op,
6739c48c75eSJung-uk Kim     UINT32                      Count,
6749c48c75eSJung-uk Kim     UINT32                      ExpectedCount)
6759c48c75eSJung-uk Kim {
6769c48c75eSJung-uk Kim 
6779c48c75eSJung-uk Kim     sprintf (MsgBuffer, "%s: length is %u, only %u required",
6789c48c75eSJung-uk Kim         PredefinedName, Count, ExpectedCount);
6799c48c75eSJung-uk Kim 
6809c48c75eSJung-uk Kim     AslError (ASL_REMARK, ASL_MSG_RESERVED_PACKAGE_LENGTH, Op, MsgBuffer);
6819c48c75eSJung-uk Kim }
682