xref: /freebsd/sys/contrib/dev/acpica/compiler/aslprepkg.c (revision 895f26a936215c6187ee6f713ce504921b6010e1)
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
97*895f26a9SJung-uk Kim  *              Predefined          - Pointer to package-specific info for
98*895f26a9SJung-uk Kim  *                                    the method
999c48c75eSJung-uk Kim  *
1009c48c75eSJung-uk Kim  * RETURN:      None
1019c48c75eSJung-uk Kim  *
1029c48c75eSJung-uk Kim  * DESCRIPTION: Top-level validation for predefined name return package
1039c48c75eSJung-uk Kim  *              objects.
1049c48c75eSJung-uk Kim  *
1059c48c75eSJung-uk Kim  ******************************************************************************/
1069c48c75eSJung-uk Kim 
1079c48c75eSJung-uk Kim void
1089c48c75eSJung-uk Kim ApCheckPackage (
1099c48c75eSJung-uk Kim     ACPI_PARSE_OBJECT           *ParentOp,
1109c48c75eSJung-uk Kim     const ACPI_PREDEFINED_INFO  *Predefined)
1119c48c75eSJung-uk Kim {
1129c48c75eSJung-uk Kim     ACPI_PARSE_OBJECT           *Op;
1139c48c75eSJung-uk Kim     const ACPI_PREDEFINED_INFO  *Package;
1149c48c75eSJung-uk Kim     ACPI_STATUS                 Status;
1159c48c75eSJung-uk Kim     UINT32                      ExpectedCount;
1169c48c75eSJung-uk Kim     UINT32                      Count;
1179c48c75eSJung-uk Kim     UINT32                      i;
1189c48c75eSJung-uk Kim 
1199c48c75eSJung-uk Kim 
1209c48c75eSJung-uk Kim     /* The package info for this name is in the next table entry */
1219c48c75eSJung-uk Kim 
1229c48c75eSJung-uk Kim     Package = Predefined + 1;
1239c48c75eSJung-uk Kim 
1249c48c75eSJung-uk Kim     /* First child is the package length */
1259c48c75eSJung-uk Kim 
1269c48c75eSJung-uk Kim     Op = ParentOp->Asl.Child;
1279c48c75eSJung-uk Kim     Count = (UINT32) Op->Asl.Value.Integer;
1289c48c75eSJung-uk Kim 
1299c48c75eSJung-uk Kim     /*
1309c7c683cSJung-uk Kim      * Many of the variable-length top-level packages are allowed to simply
1319c7c683cSJung-uk Kim      * have zero elements. This allows the BIOS to tell the host that even
1329c7c683cSJung-uk Kim      * though the predefined name/method exists, the feature is not supported.
1339c7c683cSJung-uk Kim      * Other package types require one or more elements. In any case, there
1349c7c683cSJung-uk Kim      * is no need to continue validation.
1359c48c75eSJung-uk Kim      */
1369c48c75eSJung-uk Kim     if (!Count)
1379c48c75eSJung-uk Kim     {
1389c7c683cSJung-uk Kim         switch (Package->RetInfo.Type)
1399c48c75eSJung-uk Kim         {
1409c7c683cSJung-uk Kim         case ACPI_PTYPE1_FIXED:
1419c7c683cSJung-uk Kim         case ACPI_PTYPE1_OPTION:
1429c7c683cSJung-uk Kim         case ACPI_PTYPE2_PKG_COUNT:
1439c7c683cSJung-uk Kim         case ACPI_PTYPE2_REV_FIXED:
1449c7c683cSJung-uk Kim 
1459c48c75eSJung-uk Kim             ApZeroLengthPackage (Predefined->Info.Name, ParentOp);
1469c7c683cSJung-uk Kim             break;
1479c7c683cSJung-uk Kim 
1489c7c683cSJung-uk Kim         case ACPI_PTYPE1_VAR:
1499c7c683cSJung-uk Kim         case ACPI_PTYPE2:
1509c7c683cSJung-uk Kim         case ACPI_PTYPE2_COUNT:
1519c7c683cSJung-uk Kim         case ACPI_PTYPE2_FIXED:
1529c7c683cSJung-uk Kim         case ACPI_PTYPE2_MIN:
1539c7c683cSJung-uk Kim         case ACPI_PTYPE2_FIX_VAR:
1549c7c683cSJung-uk Kim         default:
1559c7c683cSJung-uk Kim 
1569c7c683cSJung-uk Kim             break;
1579c48c75eSJung-uk Kim         }
1589c7c683cSJung-uk Kim 
1599c48c75eSJung-uk Kim         return;
1609c48c75eSJung-uk Kim     }
1619c48c75eSJung-uk Kim 
1629c48c75eSJung-uk Kim     /* Get the first element of the package */
1639c48c75eSJung-uk Kim 
1649c48c75eSJung-uk Kim     Op = Op->Asl.Next;
1659c48c75eSJung-uk Kim 
1669c48c75eSJung-uk Kim     /* Decode the package type */
1679c48c75eSJung-uk Kim 
1689c48c75eSJung-uk Kim     switch (Package->RetInfo.Type)
1699c48c75eSJung-uk Kim     {
1709c48c75eSJung-uk Kim     case ACPI_PTYPE1_FIXED:
1719c48c75eSJung-uk Kim         /*
1729c48c75eSJung-uk Kim          * The package count is fixed and there are no sub-packages
1739c48c75eSJung-uk Kim          *
1749c48c75eSJung-uk Kim          * If package is too small, exit.
1759c48c75eSJung-uk Kim          * If package is larger than expected, issue warning but continue
1769c48c75eSJung-uk Kim          */
1779c48c75eSJung-uk Kim         ExpectedCount = Package->RetInfo.Count1 + Package->RetInfo.Count2;
1789c48c75eSJung-uk Kim         if (Count < ExpectedCount)
1799c48c75eSJung-uk Kim         {
1809c48c75eSJung-uk Kim             goto PackageTooSmall;
1819c48c75eSJung-uk Kim         }
1829c48c75eSJung-uk Kim         else if (Count > ExpectedCount)
1839c48c75eSJung-uk Kim         {
1849c48c75eSJung-uk Kim             ApPackageTooLarge (Predefined->Info.Name, ParentOp,
1859c48c75eSJung-uk Kim                 Count, ExpectedCount);
1869c48c75eSJung-uk Kim         }
1879c48c75eSJung-uk Kim 
1889c48c75eSJung-uk Kim         /* Validate all elements of the package */
1899c48c75eSJung-uk Kim 
1909c48c75eSJung-uk Kim         ApCheckPackageElements (Predefined->Info.Name, Op,
1919c48c75eSJung-uk Kim             Package->RetInfo.ObjectType1, Package->RetInfo.Count1,
1929c48c75eSJung-uk Kim             Package->RetInfo.ObjectType2, Package->RetInfo.Count2);
1939c48c75eSJung-uk Kim         break;
1949c48c75eSJung-uk Kim 
1959c48c75eSJung-uk Kim     case ACPI_PTYPE1_VAR:
1969c48c75eSJung-uk Kim         /*
197*895f26a9SJung-uk Kim          * The package count is variable, there are no sub-packages,
198*895f26a9SJung-uk Kim          * and all elements must be of the same type
1999c48c75eSJung-uk Kim          */
2009c48c75eSJung-uk Kim         for (i = 0; i < Count; i++)
2019c48c75eSJung-uk Kim         {
2029c48c75eSJung-uk Kim             ApCheckObjectType (Predefined->Info.Name, Op,
2039c48c75eSJung-uk Kim                 Package->RetInfo.ObjectType1, i);
2049c48c75eSJung-uk Kim             Op = Op->Asl.Next;
2059c48c75eSJung-uk Kim         }
2069c48c75eSJung-uk Kim         break;
2079c48c75eSJung-uk Kim 
2089c48c75eSJung-uk Kim     case ACPI_PTYPE1_OPTION:
2099c48c75eSJung-uk Kim         /*
210*895f26a9SJung-uk Kim          * The package count is variable, there are no sub-packages.
211*895f26a9SJung-uk Kim          * There are a fixed number of required elements, and a variable
212*895f26a9SJung-uk Kim          * number of optional elements.
2139c48c75eSJung-uk Kim          *
2149c48c75eSJung-uk Kim          * Check if package is at least as large as the minimum required
2159c48c75eSJung-uk Kim          */
2169c48c75eSJung-uk Kim         ExpectedCount = Package->RetInfo3.Count;
2179c48c75eSJung-uk Kim         if (Count < ExpectedCount)
2189c48c75eSJung-uk Kim         {
2199c48c75eSJung-uk Kim             goto PackageTooSmall;
2209c48c75eSJung-uk Kim         }
2219c48c75eSJung-uk Kim 
2229c48c75eSJung-uk Kim         /* Variable number of sub-objects */
2239c48c75eSJung-uk Kim 
2249c48c75eSJung-uk Kim         for (i = 0; i < Count; i++)
2259c48c75eSJung-uk Kim         {
2269c48c75eSJung-uk Kim             if (i < Package->RetInfo3.Count)
2279c48c75eSJung-uk Kim             {
2289c48c75eSJung-uk Kim                 /* These are the required package elements (0, 1, or 2) */
2299c48c75eSJung-uk Kim 
2309c48c75eSJung-uk Kim                 ApCheckObjectType (Predefined->Info.Name, Op,
2319c48c75eSJung-uk Kim                     Package->RetInfo3.ObjectType[i], i);
2329c48c75eSJung-uk Kim             }
2339c48c75eSJung-uk Kim             else
2349c48c75eSJung-uk Kim             {
2359c48c75eSJung-uk Kim                 /* These are the optional package elements */
2369c48c75eSJung-uk Kim 
2379c48c75eSJung-uk Kim                 ApCheckObjectType (Predefined->Info.Name, Op,
2389c48c75eSJung-uk Kim                     Package->RetInfo3.TailObjectType, i);
2399c48c75eSJung-uk Kim             }
2409c48c75eSJung-uk Kim             Op = Op->Asl.Next;
2419c48c75eSJung-uk Kim         }
2429c48c75eSJung-uk Kim         break;
2439c48c75eSJung-uk Kim 
2449c48c75eSJung-uk Kim     case ACPI_PTYPE2_REV_FIXED:
2459c48c75eSJung-uk Kim 
2469c48c75eSJung-uk Kim         /* First element is the (Integer) revision */
2479c48c75eSJung-uk Kim 
2489c48c75eSJung-uk Kim         ApCheckObjectType (Predefined->Info.Name, Op,
2499c48c75eSJung-uk Kim             ACPI_RTYPE_INTEGER, 0);
2509c48c75eSJung-uk Kim 
2519c48c75eSJung-uk Kim         Op = Op->Asl.Next;
2529c48c75eSJung-uk Kim         Count--;
2539c48c75eSJung-uk Kim 
2549c48c75eSJung-uk Kim         /* Examine the sub-packages */
2559c48c75eSJung-uk Kim 
2569c48c75eSJung-uk Kim         ApCheckPackageList (Predefined->Info.Name, Op,
2579c48c75eSJung-uk Kim             Package, 1, Count);
2589c48c75eSJung-uk Kim         break;
2599c48c75eSJung-uk Kim 
2609c48c75eSJung-uk Kim     case ACPI_PTYPE2_PKG_COUNT:
2619c48c75eSJung-uk Kim 
2629c48c75eSJung-uk Kim         /* First element is the (Integer) count of sub-packages to follow */
2639c48c75eSJung-uk Kim 
2649c48c75eSJung-uk Kim         Status = ApCheckObjectType (Predefined->Info.Name, Op,
2659c48c75eSJung-uk Kim             ACPI_RTYPE_INTEGER, 0);
2669c48c75eSJung-uk Kim 
2679c48c75eSJung-uk Kim         /* We must have an integer count from above (otherwise, use Count) */
2689c48c75eSJung-uk Kim 
2699c48c75eSJung-uk Kim         if (ACPI_SUCCESS (Status))
2709c48c75eSJung-uk Kim         {
2719c48c75eSJung-uk Kim             /*
272*895f26a9SJung-uk Kim              * Count cannot be larger than the parent package length, but
273*895f26a9SJung-uk Kim              * allow it to be smaller. The >= accounts for the Integer above.
2749c48c75eSJung-uk Kim              */
2759c48c75eSJung-uk Kim             ExpectedCount = (UINT32) Op->Asl.Value.Integer;
2769c48c75eSJung-uk Kim             if (ExpectedCount >= Count)
2779c48c75eSJung-uk Kim             {
2789c48c75eSJung-uk Kim                 goto PackageTooSmall;
2799c48c75eSJung-uk Kim             }
2809c48c75eSJung-uk Kim 
2819c48c75eSJung-uk Kim             Count = ExpectedCount;
2829c48c75eSJung-uk Kim         }
2839c48c75eSJung-uk Kim 
2849c48c75eSJung-uk Kim         Op = Op->Asl.Next;
2859c48c75eSJung-uk Kim 
2869c48c75eSJung-uk Kim         /* Examine the sub-packages */
2879c48c75eSJung-uk Kim 
2889c48c75eSJung-uk Kim         ApCheckPackageList (Predefined->Info.Name, Op,
2899c48c75eSJung-uk Kim             Package, 1, Count);
2909c48c75eSJung-uk Kim         break;
2919c48c75eSJung-uk Kim 
2929c48c75eSJung-uk Kim     case ACPI_PTYPE2:
2939c48c75eSJung-uk Kim     case ACPI_PTYPE2_FIXED:
2949c48c75eSJung-uk Kim     case ACPI_PTYPE2_MIN:
2959c48c75eSJung-uk Kim     case ACPI_PTYPE2_COUNT:
2969c48c75eSJung-uk Kim     case ACPI_PTYPE2_FIX_VAR:
2979c48c75eSJung-uk Kim         /*
2989c48c75eSJung-uk Kim          * These types all return a single Package that consists of a
2999c48c75eSJung-uk Kim          * variable number of sub-Packages.
3009c48c75eSJung-uk Kim          */
3019c48c75eSJung-uk Kim 
3029c48c75eSJung-uk Kim         /* Examine the sub-packages */
3039c48c75eSJung-uk Kim 
3049c48c75eSJung-uk Kim         ApCheckPackageList (Predefined->Info.Name, Op,
3059c48c75eSJung-uk Kim             Package, 0, Count);
3069c48c75eSJung-uk Kim         break;
3079c48c75eSJung-uk Kim 
3089c48c75eSJung-uk Kim     default:
3099c48c75eSJung-uk Kim         return;
3109c48c75eSJung-uk Kim     }
3119c48c75eSJung-uk Kim 
3129c48c75eSJung-uk Kim     return;
3139c48c75eSJung-uk Kim 
3149c48c75eSJung-uk Kim PackageTooSmall:
3159c48c75eSJung-uk Kim     ApPackageTooSmall (Predefined->Info.Name, ParentOp,
3169c48c75eSJung-uk Kim         Count, ExpectedCount);
3179c48c75eSJung-uk Kim }
3189c48c75eSJung-uk Kim 
3199c48c75eSJung-uk Kim 
3209c48c75eSJung-uk Kim /*******************************************************************************
3219c48c75eSJung-uk Kim  *
3229c48c75eSJung-uk Kim  * FUNCTION:    ApCheckPackageElements
3239c48c75eSJung-uk Kim  *
324*895f26a9SJung-uk Kim  * PARAMETERS:  PredefinedName      - Name of the predefined object
3259c48c75eSJung-uk Kim  *              Op                  - Parser op for the package
3269c48c75eSJung-uk Kim  *              Type1               - Object type for first group
3279c48c75eSJung-uk Kim  *              Count1              - Count for first group
3289c48c75eSJung-uk Kim  *              Type2               - Object type for second group
3299c48c75eSJung-uk Kim  *              Count2              - Count for second group
3309c48c75eSJung-uk Kim  *
3319c48c75eSJung-uk Kim  * RETURN:      None
3329c48c75eSJung-uk Kim  *
3339c48c75eSJung-uk Kim  * DESCRIPTION: Validate all elements of a package. Works with packages that
3349c48c75eSJung-uk Kim  *              are defined to contain up to two groups of different object
3359c48c75eSJung-uk Kim  *              types.
3369c48c75eSJung-uk Kim  *
3379c48c75eSJung-uk Kim  ******************************************************************************/
3389c48c75eSJung-uk Kim 
3399c48c75eSJung-uk Kim static void
3409c48c75eSJung-uk Kim ApCheckPackageElements (
3419c48c75eSJung-uk Kim     const char              *PredefinedName,
3429c48c75eSJung-uk Kim     ACPI_PARSE_OBJECT       *Op,
3439c48c75eSJung-uk Kim     UINT8                   Type1,
3449c48c75eSJung-uk Kim     UINT32                  Count1,
3459c48c75eSJung-uk Kim     UINT8                   Type2,
3469c48c75eSJung-uk Kim     UINT32                  Count2)
3479c48c75eSJung-uk Kim {
3489c48c75eSJung-uk Kim     UINT32                  i;
3499c48c75eSJung-uk Kim 
3509c48c75eSJung-uk Kim 
3519c48c75eSJung-uk Kim     /*
3529c48c75eSJung-uk Kim      * Up to two groups of package elements are supported by the data
3539c48c75eSJung-uk Kim      * structure. All elements in each group must be of the same type.
3549c48c75eSJung-uk Kim      * The second group can have a count of zero.
3559c48c75eSJung-uk Kim      *
3569c48c75eSJung-uk Kim      * Aborts check upon a NULL package element, as this means (at compile
3579c48c75eSJung-uk Kim      * time) that the remainder of the package elements are also NULL
3589c48c75eSJung-uk Kim      * (This is the only way to create NULL package elements.)
3599c48c75eSJung-uk Kim      */
3609c48c75eSJung-uk Kim     for (i = 0; (i < Count1) && Op; i++)
3619c48c75eSJung-uk Kim     {
3629c48c75eSJung-uk Kim         ApCheckObjectType (PredefinedName, Op, Type1, i);
3639c48c75eSJung-uk Kim         Op = Op->Asl.Next;
3649c48c75eSJung-uk Kim     }
3659c48c75eSJung-uk Kim 
3669c48c75eSJung-uk Kim     for (i = 0; (i < Count2) && Op; i++)
3679c48c75eSJung-uk Kim     {
3689c48c75eSJung-uk Kim         ApCheckObjectType (PredefinedName, Op, Type2, (i + Count1));
3699c48c75eSJung-uk Kim         Op = Op->Asl.Next;
3709c48c75eSJung-uk Kim     }
3719c48c75eSJung-uk Kim }
3729c48c75eSJung-uk Kim 
3739c48c75eSJung-uk Kim 
3749c48c75eSJung-uk Kim /*******************************************************************************
3759c48c75eSJung-uk Kim  *
3769c48c75eSJung-uk Kim  * FUNCTION:    ApCheckPackageList
3779c48c75eSJung-uk Kim  *
3789c48c75eSJung-uk Kim  * PARAMETERS:  PredefinedName      - Name of the predefined object
3799c48c75eSJung-uk Kim  *              ParentOp            - Parser op of the parent package
3809c48c75eSJung-uk Kim  *              Package             - Package info for this predefined name
3819c48c75eSJung-uk Kim  *              StartIndex          - Index in parent package where list begins
3829c48c75eSJung-uk Kim  *              ParentCount         - Element count of parent package
3839c48c75eSJung-uk Kim  *
3849c48c75eSJung-uk Kim  * RETURN:      None
3859c48c75eSJung-uk Kim  *
3869c48c75eSJung-uk Kim  * DESCRIPTION: Validate the individual package elements for a predefined name.
3879c48c75eSJung-uk Kim  *              Handles the cases where the predefined name is defined as a
3889c48c75eSJung-uk Kim  *              Package of Packages (subpackages). These are the types:
3899c48c75eSJung-uk Kim  *
3909c48c75eSJung-uk Kim  *              ACPI_PTYPE2
3919c48c75eSJung-uk Kim  *              ACPI_PTYPE2_FIXED
3929c48c75eSJung-uk Kim  *              ACPI_PTYPE2_MIN
3939c48c75eSJung-uk Kim  *              ACPI_PTYPE2_COUNT
3949c48c75eSJung-uk Kim  *              ACPI_PTYPE2_FIX_VAR
3959c48c75eSJung-uk Kim  *
3969c48c75eSJung-uk Kim  ******************************************************************************/
3979c48c75eSJung-uk Kim 
3989c48c75eSJung-uk Kim static void
3999c48c75eSJung-uk Kim ApCheckPackageList (
4009c48c75eSJung-uk Kim     const char                  *PredefinedName,
4019c48c75eSJung-uk Kim     ACPI_PARSE_OBJECT           *ParentOp,
4029c48c75eSJung-uk Kim     const ACPI_PREDEFINED_INFO  *Package,
4039c48c75eSJung-uk Kim     UINT32                      StartIndex,
4049c48c75eSJung-uk Kim     UINT32                      ParentCount)
4059c48c75eSJung-uk Kim {
4069c48c75eSJung-uk Kim     ACPI_PARSE_OBJECT           *SubPackageOp = ParentOp;
4079c48c75eSJung-uk Kim     ACPI_PARSE_OBJECT           *Op;
4089c48c75eSJung-uk Kim     ACPI_STATUS                 Status;
4099c48c75eSJung-uk Kim     UINT32                      Count;
4109c48c75eSJung-uk Kim     UINT32                      ExpectedCount;
4119c48c75eSJung-uk Kim     UINT32                      i;
4129c48c75eSJung-uk Kim     UINT32                      j;
4139c48c75eSJung-uk Kim 
4149c48c75eSJung-uk Kim 
4159c48c75eSJung-uk Kim     /*
4169c48c75eSJung-uk Kim      * Validate each subpackage in the parent Package
4179c48c75eSJung-uk Kim      *
4189c48c75eSJung-uk Kim      * Note: We ignore NULL package elements on the assumption that
4199c48c75eSJung-uk Kim      * they will be initialized by the BIOS or other ASL code.
4209c48c75eSJung-uk Kim      */
4219c48c75eSJung-uk Kim     for (i = 0; (i < ParentCount) && SubPackageOp; i++)
4229c48c75eSJung-uk Kim     {
4239c48c75eSJung-uk Kim         /* Each object in the list must be of type Package */
4249c48c75eSJung-uk Kim 
4259c48c75eSJung-uk Kim         Status = ApCheckObjectType (PredefinedName, SubPackageOp,
4269c48c75eSJung-uk Kim             ACPI_RTYPE_PACKAGE, i + StartIndex);
4279c48c75eSJung-uk Kim         if (ACPI_FAILURE (Status))
4289c48c75eSJung-uk Kim         {
4299c48c75eSJung-uk Kim             goto NextSubpackage;
4309c48c75eSJung-uk Kim         }
4319c48c75eSJung-uk Kim 
4329c48c75eSJung-uk Kim         /* Examine the different types of expected subpackages */
4339c48c75eSJung-uk Kim 
4349c48c75eSJung-uk Kim         Op = SubPackageOp->Asl.Child;
4359c48c75eSJung-uk Kim 
4369c48c75eSJung-uk Kim         /* First child is the package length */
4379c48c75eSJung-uk Kim 
4389c48c75eSJung-uk Kim         Count = (UINT32) Op->Asl.Value.Integer;
4399c48c75eSJung-uk Kim         Op = Op->Asl.Next;
4409c48c75eSJung-uk Kim 
4419c48c75eSJung-uk Kim         /* The subpackage must have at least one element */
4429c48c75eSJung-uk Kim 
4439c48c75eSJung-uk Kim         if (!Count)
4449c48c75eSJung-uk Kim         {
4459c48c75eSJung-uk Kim             ApZeroLengthPackage (PredefinedName, SubPackageOp);
4469c48c75eSJung-uk Kim             goto NextSubpackage;
4479c48c75eSJung-uk Kim         }
4489c48c75eSJung-uk Kim 
4499c48c75eSJung-uk Kim         /*
4509c48c75eSJung-uk Kim          * Decode the package type.
4519c48c75eSJung-uk Kim          * PTYPE2 indicates that a "package of packages" is expected for
4529c48c75eSJung-uk Kim          * this name. The various flavors of PTYPE2 indicate the number
4539c48c75eSJung-uk Kim          * and format of the subpackages.
4549c48c75eSJung-uk Kim          */
4559c48c75eSJung-uk Kim         switch (Package->RetInfo.Type)
4569c48c75eSJung-uk Kim         {
4579c48c75eSJung-uk Kim         case ACPI_PTYPE2:
4589c48c75eSJung-uk Kim         case ACPI_PTYPE2_PKG_COUNT:
4599c48c75eSJung-uk Kim         case ACPI_PTYPE2_REV_FIXED:
4609c48c75eSJung-uk Kim 
4619c48c75eSJung-uk Kim             /* Each subpackage has a fixed number of elements */
4629c48c75eSJung-uk Kim 
4639c48c75eSJung-uk Kim             ExpectedCount = Package->RetInfo.Count1 + Package->RetInfo.Count2;
4649c48c75eSJung-uk Kim             if (Count < ExpectedCount)
4659c48c75eSJung-uk Kim             {
4669c48c75eSJung-uk Kim                 ApPackageTooSmall (PredefinedName, SubPackageOp,
4679c48c75eSJung-uk Kim                     Count, ExpectedCount);
4689c48c75eSJung-uk Kim                 break;
4699c48c75eSJung-uk Kim             }
4709c48c75eSJung-uk Kim 
4719c48c75eSJung-uk Kim             ApCheckPackageElements (PredefinedName, Op,
4729c48c75eSJung-uk Kim                 Package->RetInfo.ObjectType1, Package->RetInfo.Count1,
4739c48c75eSJung-uk Kim                 Package->RetInfo.ObjectType2, Package->RetInfo.Count2);
4749c48c75eSJung-uk Kim             break;
4759c48c75eSJung-uk Kim 
4769c48c75eSJung-uk Kim         case ACPI_PTYPE2_FIX_VAR:
4779c48c75eSJung-uk Kim             /*
4789c48c75eSJung-uk Kim              * Each subpackage has a fixed number of elements and an
4799c48c75eSJung-uk Kim              * optional element
4809c48c75eSJung-uk Kim              */
4819c48c75eSJung-uk Kim             ExpectedCount = Package->RetInfo.Count1 + Package->RetInfo.Count2;
4829c48c75eSJung-uk Kim             if (Count < ExpectedCount)
4839c48c75eSJung-uk Kim             {
4849c48c75eSJung-uk Kim                 ApPackageTooSmall (PredefinedName, SubPackageOp,
4859c48c75eSJung-uk Kim                     Count, ExpectedCount);
4869c48c75eSJung-uk Kim                 break;
4879c48c75eSJung-uk Kim             }
4889c48c75eSJung-uk Kim 
4899c48c75eSJung-uk Kim             ApCheckPackageElements (PredefinedName, Op,
4909c48c75eSJung-uk Kim                 Package->RetInfo.ObjectType1, Package->RetInfo.Count1,
4919c48c75eSJung-uk Kim                 Package->RetInfo.ObjectType2,
4929c48c75eSJung-uk Kim                 Count - Package->RetInfo.Count1);
4939c48c75eSJung-uk Kim             break;
4949c48c75eSJung-uk Kim 
4959c48c75eSJung-uk Kim         case ACPI_PTYPE2_FIXED:
4969c48c75eSJung-uk Kim 
4979c48c75eSJung-uk Kim             /* Each sub-package has a fixed length */
4989c48c75eSJung-uk Kim 
4999c48c75eSJung-uk Kim             ExpectedCount = Package->RetInfo2.Count;
5009c48c75eSJung-uk Kim             if (Count < ExpectedCount)
5019c48c75eSJung-uk Kim             {
5029c48c75eSJung-uk Kim                 ApPackageTooSmall (PredefinedName, SubPackageOp,
5039c48c75eSJung-uk Kim                     Count, ExpectedCount);
5049c48c75eSJung-uk Kim                 break;
5059c48c75eSJung-uk Kim             }
5069c48c75eSJung-uk Kim 
5079c48c75eSJung-uk Kim             /* Check each object/type combination */
5089c48c75eSJung-uk Kim 
5099c48c75eSJung-uk Kim             for (j = 0; j < ExpectedCount; j++)
5109c48c75eSJung-uk Kim             {
5119c48c75eSJung-uk Kim                 ApCheckObjectType (PredefinedName, Op,
5129c48c75eSJung-uk Kim                     Package->RetInfo2.ObjectType[j], j);
5139c48c75eSJung-uk Kim 
5149c48c75eSJung-uk Kim                 Op = Op->Asl.Next;
5159c48c75eSJung-uk Kim             }
5169c48c75eSJung-uk Kim             break;
5179c48c75eSJung-uk Kim 
5189c48c75eSJung-uk Kim         case ACPI_PTYPE2_MIN:
5199c48c75eSJung-uk Kim 
5209c48c75eSJung-uk Kim             /* Each sub-package has a variable but minimum length */
5219c48c75eSJung-uk Kim 
5229c48c75eSJung-uk Kim             ExpectedCount = Package->RetInfo.Count1;
5239c48c75eSJung-uk Kim             if (Count < ExpectedCount)
5249c48c75eSJung-uk Kim             {
5259c48c75eSJung-uk Kim                 ApPackageTooSmall (PredefinedName, SubPackageOp,
5269c48c75eSJung-uk Kim                     Count, ExpectedCount);
5279c48c75eSJung-uk Kim                 break;
5289c48c75eSJung-uk Kim             }
5299c48c75eSJung-uk Kim 
5309c48c75eSJung-uk Kim             /* Check the type of each sub-package element */
5319c48c75eSJung-uk Kim 
5329c48c75eSJung-uk Kim             ApCheckPackageElements (PredefinedName, Op,
5339c48c75eSJung-uk Kim                 Package->RetInfo.ObjectType1, Count, 0, 0);
5349c48c75eSJung-uk Kim             break;
5359c48c75eSJung-uk Kim 
5369c48c75eSJung-uk Kim         case ACPI_PTYPE2_COUNT:
5379c48c75eSJung-uk Kim             /*
5389c48c75eSJung-uk Kim              * First element is the (Integer) count of elements, including
5399c48c75eSJung-uk Kim              * the count field (the ACPI name is NumElements)
5409c48c75eSJung-uk Kim              */
5419c48c75eSJung-uk Kim             Status = ApCheckObjectType (PredefinedName, Op,
5429c48c75eSJung-uk Kim                 ACPI_RTYPE_INTEGER, 0);
5439c48c75eSJung-uk Kim 
5449c48c75eSJung-uk Kim             /* We must have an integer count from above (otherwise, use Count) */
5459c48c75eSJung-uk Kim 
5469c48c75eSJung-uk Kim             if (ACPI_SUCCESS (Status))
5479c48c75eSJung-uk Kim             {
5489c48c75eSJung-uk Kim                 /*
5499c48c75eSJung-uk Kim                  * Make sure package is large enough for the Count and is
5509c48c75eSJung-uk Kim                  * is as large as the minimum size
5519c48c75eSJung-uk Kim                  */
5529c48c75eSJung-uk Kim                 ExpectedCount = (UINT32) Op->Asl.Value.Integer;
5539c48c75eSJung-uk Kim 
5549c48c75eSJung-uk Kim                 if (Count < ExpectedCount)
5559c48c75eSJung-uk Kim                 {
5569c48c75eSJung-uk Kim                     ApPackageTooSmall (PredefinedName, SubPackageOp,
5579c48c75eSJung-uk Kim                         Count, ExpectedCount);
5589c48c75eSJung-uk Kim                     break;
5599c48c75eSJung-uk Kim                 }
5609c48c75eSJung-uk Kim                 else if (Count > ExpectedCount)
5619c48c75eSJung-uk Kim                 {
5629c48c75eSJung-uk Kim                     ApPackageTooLarge (PredefinedName, SubPackageOp,
5639c48c75eSJung-uk Kim                         Count, ExpectedCount);
5649c48c75eSJung-uk Kim                 }
5659c48c75eSJung-uk Kim 
5669c48c75eSJung-uk Kim                 /* Some names of this type have a minimum length */
5679c48c75eSJung-uk Kim 
5689c48c75eSJung-uk Kim                 if (Count < Package->RetInfo.Count1)
5699c48c75eSJung-uk Kim                 {
5709c48c75eSJung-uk Kim                     ExpectedCount = Package->RetInfo.Count1;
5719c48c75eSJung-uk Kim                     ApPackageTooSmall (PredefinedName, SubPackageOp,
5729c48c75eSJung-uk Kim                         Count, ExpectedCount);
5739c48c75eSJung-uk Kim                     break;
5749c48c75eSJung-uk Kim                 }
5759c48c75eSJung-uk Kim 
5769c48c75eSJung-uk Kim                 Count = ExpectedCount;
5779c48c75eSJung-uk Kim             }
5789c48c75eSJung-uk Kim 
5799c48c75eSJung-uk Kim             /* Check the type of each sub-package element */
5809c48c75eSJung-uk Kim 
5819c48c75eSJung-uk Kim             Op = Op->Asl.Next;
5829c48c75eSJung-uk Kim             ApCheckPackageElements (PredefinedName, Op,
5839c48c75eSJung-uk Kim                 Package->RetInfo.ObjectType1, (Count - 1), 0, 0);
5849c48c75eSJung-uk Kim             break;
5859c48c75eSJung-uk Kim 
5869c48c75eSJung-uk Kim         default:
5879c48c75eSJung-uk Kim             break;
5889c48c75eSJung-uk Kim         }
5899c48c75eSJung-uk Kim 
5909c48c75eSJung-uk Kim NextSubpackage:
5919c48c75eSJung-uk Kim         SubPackageOp = SubPackageOp->Asl.Next;
5929c48c75eSJung-uk Kim     }
5939c48c75eSJung-uk Kim }
5949c48c75eSJung-uk Kim 
5959c48c75eSJung-uk Kim 
5969c48c75eSJung-uk Kim /*******************************************************************************
5979c48c75eSJung-uk Kim  *
5989c48c75eSJung-uk Kim  * FUNCTION:    ApPackageTooSmall
5999c48c75eSJung-uk Kim  *
6009c48c75eSJung-uk Kim  * PARAMETERS:  PredefinedName      - Name of the predefined object
6019c48c75eSJung-uk Kim  *              Op                  - Current parser op
6029c48c75eSJung-uk Kim  *              Count               - Actual package element count
6039c48c75eSJung-uk Kim  *              ExpectedCount       - Expected package element count
6049c48c75eSJung-uk Kim  *
6059c48c75eSJung-uk Kim  * RETURN:      None
6069c48c75eSJung-uk Kim  *
6079c48c75eSJung-uk Kim  * DESCRIPTION: Issue error message for a package that is smaller than
6089c48c75eSJung-uk Kim  *              required.
6099c48c75eSJung-uk Kim  *
6109c48c75eSJung-uk Kim  ******************************************************************************/
6119c48c75eSJung-uk Kim 
6129c48c75eSJung-uk Kim static void
6139c48c75eSJung-uk Kim ApPackageTooSmall (
6149c48c75eSJung-uk Kim     const char                  *PredefinedName,
6159c48c75eSJung-uk Kim     ACPI_PARSE_OBJECT           *Op,
6169c48c75eSJung-uk Kim     UINT32                      Count,
6179c48c75eSJung-uk Kim     UINT32                      ExpectedCount)
6189c48c75eSJung-uk Kim {
6199c48c75eSJung-uk Kim 
6209c48c75eSJung-uk Kim     sprintf (MsgBuffer, "%s: length %u, required minimum is %u",
6219c48c75eSJung-uk Kim         PredefinedName, Count, ExpectedCount);
6229c48c75eSJung-uk Kim 
6239c48c75eSJung-uk Kim     AslError (ASL_ERROR, ASL_MSG_RESERVED_PACKAGE_LENGTH, Op, MsgBuffer);
6249c48c75eSJung-uk Kim }
6259c48c75eSJung-uk Kim 
6269c48c75eSJung-uk Kim 
6279c48c75eSJung-uk Kim /*******************************************************************************
6289c48c75eSJung-uk Kim  *
6299c48c75eSJung-uk Kim  * FUNCTION:    ApZeroLengthPackage
6309c48c75eSJung-uk Kim  *
6319c48c75eSJung-uk Kim  * PARAMETERS:  PredefinedName      - Name of the predefined object
6329c48c75eSJung-uk Kim  *              Op                  - Current parser op
6339c48c75eSJung-uk Kim  *
6349c48c75eSJung-uk Kim  * RETURN:      None
6359c48c75eSJung-uk Kim  *
6369c48c75eSJung-uk Kim  * DESCRIPTION: Issue error message for a zero-length package (a package that
6379c48c75eSJung-uk Kim  *              is required to have a non-zero length). Variable length
6389c48c75eSJung-uk Kim  *              packages seem to be allowed to have zero length, however.
6399c48c75eSJung-uk Kim  *              Even if not allowed, BIOS code does it.
6409c48c75eSJung-uk Kim  *
6419c48c75eSJung-uk Kim  ******************************************************************************/
6429c48c75eSJung-uk Kim 
6439c48c75eSJung-uk Kim static void
6449c48c75eSJung-uk Kim ApZeroLengthPackage (
6459c48c75eSJung-uk Kim     const char                  *PredefinedName,
6469c48c75eSJung-uk Kim     ACPI_PARSE_OBJECT           *Op)
6479c48c75eSJung-uk Kim {
6489c48c75eSJung-uk Kim 
6499c48c75eSJung-uk Kim     sprintf (MsgBuffer, "%s: length is zero", PredefinedName);
6509c48c75eSJung-uk Kim 
6519c48c75eSJung-uk Kim     AslError (ASL_ERROR, ASL_MSG_RESERVED_PACKAGE_LENGTH, Op, MsgBuffer);
6529c48c75eSJung-uk Kim }
6539c48c75eSJung-uk Kim 
6549c48c75eSJung-uk Kim 
6559c48c75eSJung-uk Kim /*******************************************************************************
6569c48c75eSJung-uk Kim  *
6579c48c75eSJung-uk Kim  * FUNCTION:    ApPackageTooLarge
6589c48c75eSJung-uk Kim  *
6599c48c75eSJung-uk Kim  * PARAMETERS:  PredefinedName      - Name of the predefined object
6609c48c75eSJung-uk Kim  *              Op                  - Current parser op
6619c48c75eSJung-uk Kim  *              Count               - Actual package element count
6629c48c75eSJung-uk Kim  *              ExpectedCount       - Expected package element count
6639c48c75eSJung-uk Kim  *
6649c48c75eSJung-uk Kim  * RETURN:      None
6659c48c75eSJung-uk Kim  *
6669c48c75eSJung-uk Kim  * DESCRIPTION: Issue a remark for a package that is larger than expected.
6679c48c75eSJung-uk Kim  *
6689c48c75eSJung-uk Kim  ******************************************************************************/
6699c48c75eSJung-uk Kim 
6709c48c75eSJung-uk Kim static void
6719c48c75eSJung-uk Kim ApPackageTooLarge (
6729c48c75eSJung-uk Kim     const char                  *PredefinedName,
6739c48c75eSJung-uk Kim     ACPI_PARSE_OBJECT           *Op,
6749c48c75eSJung-uk Kim     UINT32                      Count,
6759c48c75eSJung-uk Kim     UINT32                      ExpectedCount)
6769c48c75eSJung-uk Kim {
6779c48c75eSJung-uk Kim 
6789c48c75eSJung-uk Kim     sprintf (MsgBuffer, "%s: length is %u, only %u required",
6799c48c75eSJung-uk Kim         PredefinedName, Count, ExpectedCount);
6809c48c75eSJung-uk Kim 
6819c48c75eSJung-uk Kim     AslError (ASL_REMARK, ASL_MSG_RESERVED_PACKAGE_LENGTH, Op, MsgBuffer);
6829c48c75eSJung-uk Kim }
683