1246847Sjkim/******************************************************************************
2246847Sjkim *
3246847Sjkim * Module Name: aslprepkg - support for ACPI predefined name package objects
4246847Sjkim *
5246847Sjkim *****************************************************************************/
6246847Sjkim
7246847Sjkim/*
8281075Sdim * Copyright (C) 2000 - 2015, Intel Corp.
9246847Sjkim * All rights reserved.
10246847Sjkim *
11246847Sjkim * Redistribution and use in source and binary forms, with or without
12246847Sjkim * modification, are permitted provided that the following conditions
13246847Sjkim * are met:
14246847Sjkim * 1. Redistributions of source code must retain the above copyright
15246847Sjkim *    notice, this list of conditions, and the following disclaimer,
16246847Sjkim *    without modification.
17246847Sjkim * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18246847Sjkim *    substantially similar to the "NO WARRANTY" disclaimer below
19246847Sjkim *    ("Disclaimer") and any redistribution must be conditioned upon
20246847Sjkim *    including a substantially similar Disclaimer requirement for further
21246847Sjkim *    binary redistribution.
22246847Sjkim * 3. Neither the names of the above-listed copyright holders nor the names
23246847Sjkim *    of any contributors may be used to endorse or promote products derived
24246847Sjkim *    from this software without specific prior written permission.
25246847Sjkim *
26246847Sjkim * Alternatively, this software may be distributed under the terms of the
27246847Sjkim * GNU General Public License ("GPL") version 2 as published by the Free
28246847Sjkim * Software Foundation.
29246847Sjkim *
30246847Sjkim * NO WARRANTY
31246847Sjkim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32246847Sjkim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33246847Sjkim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34246847Sjkim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35246847Sjkim * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36246847Sjkim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37246847Sjkim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38246847Sjkim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39246847Sjkim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40246847Sjkim * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41246847Sjkim * POSSIBILITY OF SUCH DAMAGES.
42246847Sjkim */
43246847Sjkim
44246849Sjkim#include <contrib/dev/acpica/compiler/aslcompiler.h>
45246847Sjkim#include "aslcompiler.y.h"
46246849Sjkim#include <contrib/dev/acpica/include/acpredef.h>
47246847Sjkim
48246847Sjkim
49246847Sjkim#define _COMPONENT          ACPI_COMPILER
50246847Sjkim        ACPI_MODULE_NAME    ("aslprepkg")
51246847Sjkim
52246847Sjkim
53246847Sjkim/* Local prototypes */
54246847Sjkim
55246847Sjkimstatic void
56246847SjkimApCheckPackageElements (
57249663Sjkim    const char                  *PredefinedName,
58249663Sjkim    ACPI_PARSE_OBJECT           *Op,
59249663Sjkim    UINT8                       Type1,
60249663Sjkim    UINT32                      Count1,
61249663Sjkim    UINT8                       Type2,
62249663Sjkim    UINT32                      Count2);
63246847Sjkim
64246847Sjkimstatic void
65246847SjkimApCheckPackageList (
66246847Sjkim    const char                  *PredefinedName,
67246847Sjkim    ACPI_PARSE_OBJECT           *ParentOp,
68246847Sjkim    const ACPI_PREDEFINED_INFO  *Package,
69246847Sjkim    UINT32                      StartIndex,
70246847Sjkim    UINT32                      Count);
71246847Sjkim
72246847Sjkimstatic void
73246847SjkimApPackageTooSmall (
74246847Sjkim    const char                  *PredefinedName,
75246847Sjkim    ACPI_PARSE_OBJECT           *Op,
76246847Sjkim    UINT32                      Count,
77246847Sjkim    UINT32                      ExpectedCount);
78246847Sjkim
79246847Sjkimstatic void
80246847SjkimApZeroLengthPackage (
81246847Sjkim    const char                  *PredefinedName,
82246847Sjkim    ACPI_PARSE_OBJECT           *Op);
83246847Sjkim
84246847Sjkimstatic void
85246847SjkimApPackageTooLarge (
86246847Sjkim    const char                  *PredefinedName,
87246847Sjkim    ACPI_PARSE_OBJECT           *Op,
88246847Sjkim    UINT32                      Count,
89246847Sjkim    UINT32                      ExpectedCount);
90246847Sjkim
91246847Sjkim
92246847Sjkim/*******************************************************************************
93246847Sjkim *
94246847Sjkim * FUNCTION:    ApCheckPackage
95246847Sjkim *
96249663Sjkim * PARAMETERS:  ParentOp            - Parser op for the package
97249663Sjkim *              Predefined          - Pointer to package-specific info for
98249663Sjkim *                                    the method
99246847Sjkim *
100246847Sjkim * RETURN:      None
101246847Sjkim *
102246847Sjkim * DESCRIPTION: Top-level validation for predefined name return package
103246847Sjkim *              objects.
104246847Sjkim *
105246847Sjkim ******************************************************************************/
106246847Sjkim
107246847Sjkimvoid
108246847SjkimApCheckPackage (
109246847Sjkim    ACPI_PARSE_OBJECT           *ParentOp,
110246847Sjkim    const ACPI_PREDEFINED_INFO  *Predefined)
111246847Sjkim{
112246847Sjkim    ACPI_PARSE_OBJECT           *Op;
113246847Sjkim    const ACPI_PREDEFINED_INFO  *Package;
114246847Sjkim    ACPI_STATUS                 Status;
115246847Sjkim    UINT32                      ExpectedCount;
116246847Sjkim    UINT32                      Count;
117246847Sjkim    UINT32                      i;
118246847Sjkim
119246847Sjkim
120246847Sjkim    /* The package info for this name is in the next table entry */
121246847Sjkim
122246847Sjkim    Package = Predefined + 1;
123246847Sjkim
124246847Sjkim    /* First child is the package length */
125246847Sjkim
126246847Sjkim    Op = ParentOp->Asl.Child;
127246847Sjkim    Count = (UINT32) Op->Asl.Value.Integer;
128246847Sjkim
129246847Sjkim    /*
130249112Sjkim     * Many of the variable-length top-level packages are allowed to simply
131249112Sjkim     * have zero elements. This allows the BIOS to tell the host that even
132249112Sjkim     * though the predefined name/method exists, the feature is not supported.
133249112Sjkim     * Other package types require one or more elements. In any case, there
134249112Sjkim     * is no need to continue validation.
135246847Sjkim     */
136246847Sjkim    if (!Count)
137246847Sjkim    {
138249112Sjkim        switch (Package->RetInfo.Type)
139246847Sjkim        {
140249112Sjkim        case ACPI_PTYPE1_FIXED:
141249112Sjkim        case ACPI_PTYPE1_OPTION:
142249112Sjkim        case ACPI_PTYPE2_PKG_COUNT:
143249112Sjkim        case ACPI_PTYPE2_REV_FIXED:
144249112Sjkim
145246847Sjkim            ApZeroLengthPackage (Predefined->Info.Name, ParentOp);
146249112Sjkim            break;
147249112Sjkim
148249112Sjkim        case ACPI_PTYPE1_VAR:
149249112Sjkim        case ACPI_PTYPE2:
150249112Sjkim        case ACPI_PTYPE2_COUNT:
151249112Sjkim        case ACPI_PTYPE2_FIXED:
152249112Sjkim        case ACPI_PTYPE2_MIN:
153249112Sjkim        case ACPI_PTYPE2_FIX_VAR:
154284460Sjkim        case ACPI_PTYPE2_VAR_VAR:
155249112Sjkim        default:
156249112Sjkim
157249112Sjkim            break;
158246847Sjkim        }
159249112Sjkim
160246847Sjkim        return;
161246847Sjkim    }
162246847Sjkim
163246847Sjkim    /* Get the first element of the package */
164246847Sjkim
165246847Sjkim    Op = Op->Asl.Next;
166246847Sjkim
167246847Sjkim    /* Decode the package type */
168246847Sjkim
169246847Sjkim    switch (Package->RetInfo.Type)
170246847Sjkim    {
171246847Sjkim    case ACPI_PTYPE1_FIXED:
172246847Sjkim        /*
173281075Sdim         * The package count is fixed and there are no subpackages
174246847Sjkim         *
175246847Sjkim         * If package is too small, exit.
176246847Sjkim         * If package is larger than expected, issue warning but continue
177246847Sjkim         */
178246847Sjkim        ExpectedCount = Package->RetInfo.Count1 + Package->RetInfo.Count2;
179246847Sjkim        if (Count < ExpectedCount)
180246847Sjkim        {
181246847Sjkim            goto PackageTooSmall;
182246847Sjkim        }
183246847Sjkim        else if (Count > ExpectedCount)
184246847Sjkim        {
185246847Sjkim            ApPackageTooLarge (Predefined->Info.Name, ParentOp,
186246847Sjkim                Count, ExpectedCount);
187246847Sjkim        }
188246847Sjkim
189246847Sjkim        /* Validate all elements of the package */
190246847Sjkim
191246847Sjkim        ApCheckPackageElements (Predefined->Info.Name, Op,
192246847Sjkim            Package->RetInfo.ObjectType1, Package->RetInfo.Count1,
193246847Sjkim            Package->RetInfo.ObjectType2, Package->RetInfo.Count2);
194246847Sjkim        break;
195246847Sjkim
196246847Sjkim    case ACPI_PTYPE1_VAR:
197246847Sjkim        /*
198281075Sdim         * The package count is variable, there are no subpackages,
199249663Sjkim         * and all elements must be of the same type
200246847Sjkim         */
201246847Sjkim        for (i = 0; i < Count; i++)
202246847Sjkim        {
203246847Sjkim            ApCheckObjectType (Predefined->Info.Name, Op,
204246847Sjkim                Package->RetInfo.ObjectType1, i);
205246847Sjkim            Op = Op->Asl.Next;
206246847Sjkim        }
207246847Sjkim        break;
208246847Sjkim
209246847Sjkim    case ACPI_PTYPE1_OPTION:
210246847Sjkim        /*
211281075Sdim         * The package count is variable, there are no subpackages.
212249663Sjkim         * There are a fixed number of required elements, and a variable
213249663Sjkim         * number of optional elements.
214246847Sjkim         *
215246847Sjkim         * Check if package is at least as large as the minimum required
216246847Sjkim         */
217246847Sjkim        ExpectedCount = Package->RetInfo3.Count;
218246847Sjkim        if (Count < ExpectedCount)
219246847Sjkim        {
220246847Sjkim            goto PackageTooSmall;
221246847Sjkim        }
222246847Sjkim
223246847Sjkim        /* Variable number of sub-objects */
224246847Sjkim
225246847Sjkim        for (i = 0; i < Count; i++)
226246847Sjkim        {
227246847Sjkim            if (i < Package->RetInfo3.Count)
228246847Sjkim            {
229246847Sjkim                /* These are the required package elements (0, 1, or 2) */
230246847Sjkim
231246847Sjkim                ApCheckObjectType (Predefined->Info.Name, Op,
232246847Sjkim                    Package->RetInfo3.ObjectType[i], i);
233246847Sjkim            }
234246847Sjkim            else
235246847Sjkim            {
236246847Sjkim                /* These are the optional package elements */
237246847Sjkim
238246847Sjkim                ApCheckObjectType (Predefined->Info.Name, Op,
239246847Sjkim                    Package->RetInfo3.TailObjectType, i);
240246847Sjkim            }
241246847Sjkim            Op = Op->Asl.Next;
242246847Sjkim        }
243246847Sjkim        break;
244246847Sjkim
245246847Sjkim    case ACPI_PTYPE2_REV_FIXED:
246246847Sjkim
247246847Sjkim        /* First element is the (Integer) revision */
248246847Sjkim
249246847Sjkim        ApCheckObjectType (Predefined->Info.Name, Op,
250246847Sjkim            ACPI_RTYPE_INTEGER, 0);
251246847Sjkim
252246847Sjkim        Op = Op->Asl.Next;
253246847Sjkim        Count--;
254246847Sjkim
255281075Sdim        /* Examine the subpackages */
256246847Sjkim
257246847Sjkim        ApCheckPackageList (Predefined->Info.Name, Op,
258246847Sjkim            Package, 1, Count);
259246847Sjkim        break;
260246847Sjkim
261246847Sjkim    case ACPI_PTYPE2_PKG_COUNT:
262246847Sjkim
263281075Sdim        /* First element is the (Integer) count of subpackages to follow */
264246847Sjkim
265246847Sjkim        Status = ApCheckObjectType (Predefined->Info.Name, Op,
266246847Sjkim            ACPI_RTYPE_INTEGER, 0);
267246847Sjkim
268246847Sjkim        /* We must have an integer count from above (otherwise, use Count) */
269246847Sjkim
270246847Sjkim        if (ACPI_SUCCESS (Status))
271246847Sjkim        {
272246847Sjkim            /*
273249663Sjkim             * Count cannot be larger than the parent package length, but
274249663Sjkim             * allow it to be smaller. The >= accounts for the Integer above.
275246847Sjkim             */
276246847Sjkim            ExpectedCount = (UINT32) Op->Asl.Value.Integer;
277246847Sjkim            if (ExpectedCount >= Count)
278246847Sjkim            {
279246847Sjkim                goto PackageTooSmall;
280246847Sjkim            }
281246847Sjkim
282246847Sjkim            Count = ExpectedCount;
283246847Sjkim        }
284246847Sjkim
285246847Sjkim        Op = Op->Asl.Next;
286246847Sjkim
287281075Sdim        /* Examine the subpackages */
288246847Sjkim
289246847Sjkim        ApCheckPackageList (Predefined->Info.Name, Op,
290246847Sjkim            Package, 1, Count);
291246847Sjkim        break;
292246847Sjkim
293281075Sdim    case ACPI_PTYPE2_UUID_PAIR:
294281075Sdim
295281075Sdim        /* The package contains a variable list of UUID Buffer/Package pairs */
296281075Sdim
297281075Sdim        /* The length of the package must be even */
298281075Sdim
299281075Sdim        if (Count & 1)
300281075Sdim        {
301281075Sdim            sprintf (MsgBuffer, "%4.4s: Package length, %d, must be even.",
302281075Sdim                Predefined->Info.Name, Count);
303281075Sdim
304281075Sdim            AslError (ASL_ERROR, ASL_MSG_RESERVED_PACKAGE_LENGTH,
305281075Sdim                ParentOp->Asl.Child, MsgBuffer);
306281075Sdim        }
307281075Sdim
308281075Sdim        /* Validate the alternating types */
309281075Sdim
310281075Sdim        for (i = 0; i < Count; ++i)
311281075Sdim        {
312281075Sdim            if (i & 1)
313281075Sdim            {
314281075Sdim                ApCheckObjectType (Predefined->Info.Name, Op,
315281075Sdim                    Package->RetInfo.ObjectType2, i);
316281075Sdim            }
317281075Sdim            else
318281075Sdim            {
319281075Sdim                ApCheckObjectType (Predefined->Info.Name, Op,
320281075Sdim                    Package->RetInfo.ObjectType1, i);
321281075Sdim            }
322281075Sdim
323281075Sdim            Op = Op->Asl.Next;
324281075Sdim        }
325281075Sdim
326281075Sdim        break;
327281075Sdim
328284460Sjkim    case ACPI_PTYPE2_VAR_VAR:
329284460Sjkim
330284460Sjkim        /* Check for minimum size (ints at beginning + 1 subpackage) */
331284460Sjkim
332284460Sjkim        ExpectedCount = Package->RetInfo4.Count1 + 1;
333284460Sjkim        if (Count < ExpectedCount)
334284460Sjkim        {
335284460Sjkim            goto PackageTooSmall;
336284460Sjkim        }
337284460Sjkim
338284460Sjkim        /* Check the non-package elements at beginning of main package */
339284460Sjkim
340284460Sjkim        for (i = 0; i < Package->RetInfo4.Count1; ++i)
341284460Sjkim        {
342284460Sjkim            Status = ApCheckObjectType (Predefined->Info.Name, Op,
343284460Sjkim                Package->RetInfo4.ObjectType1, i);
344284460Sjkim            Op = Op->Asl.Next;
345284460Sjkim        }
346284460Sjkim
347284460Sjkim        /* Examine the variable-length list of subpackages */
348284460Sjkim
349284460Sjkim        ApCheckPackageList (Predefined->Info.Name, Op,
350284460Sjkim            Package, Package->RetInfo4.Count1, Count);
351284460Sjkim
352284460Sjkim        break;
353284460Sjkim
354246847Sjkim    case ACPI_PTYPE2:
355246847Sjkim    case ACPI_PTYPE2_FIXED:
356246847Sjkim    case ACPI_PTYPE2_MIN:
357246847Sjkim    case ACPI_PTYPE2_COUNT:
358246847Sjkim    case ACPI_PTYPE2_FIX_VAR:
359246847Sjkim        /*
360246847Sjkim         * These types all return a single Package that consists of a
361281075Sdim         * variable number of subpackages.
362246847Sjkim         */
363246847Sjkim
364281075Sdim        /* Examine the subpackages */
365246847Sjkim
366246847Sjkim        ApCheckPackageList (Predefined->Info.Name, Op,
367246847Sjkim            Package, 0, Count);
368246847Sjkim        break;
369246847Sjkim
370246847Sjkim    default:
371246847Sjkim        return;
372246847Sjkim    }
373246847Sjkim
374246847Sjkim    return;
375246847Sjkim
376246847SjkimPackageTooSmall:
377246847Sjkim    ApPackageTooSmall (Predefined->Info.Name, ParentOp,
378246847Sjkim        Count, ExpectedCount);
379246847Sjkim}
380246847Sjkim
381246847Sjkim
382246847Sjkim/*******************************************************************************
383246847Sjkim *
384246847Sjkim * FUNCTION:    ApCheckPackageElements
385246847Sjkim *
386249663Sjkim * PARAMETERS:  PredefinedName      - Name of the predefined object
387249663Sjkim *              Op                  - Parser op for the package
388249663Sjkim *              Type1               - Object type for first group
389249663Sjkim *              Count1              - Count for first group
390249663Sjkim *              Type2               - Object type for second group
391249663Sjkim *              Count2              - Count for second group
392246847Sjkim *
393246847Sjkim * RETURN:      None
394246847Sjkim *
395246847Sjkim * DESCRIPTION: Validate all elements of a package. Works with packages that
396246847Sjkim *              are defined to contain up to two groups of different object
397246847Sjkim *              types.
398246847Sjkim *
399246847Sjkim ******************************************************************************/
400246847Sjkim
401246847Sjkimstatic void
402246847SjkimApCheckPackageElements (
403246847Sjkim    const char              *PredefinedName,
404246847Sjkim    ACPI_PARSE_OBJECT       *Op,
405246847Sjkim    UINT8                   Type1,
406246847Sjkim    UINT32                  Count1,
407246847Sjkim    UINT8                   Type2,
408246847Sjkim    UINT32                  Count2)
409246847Sjkim{
410246847Sjkim    UINT32                  i;
411246847Sjkim
412246847Sjkim
413246847Sjkim    /*
414246847Sjkim     * Up to two groups of package elements are supported by the data
415246847Sjkim     * structure. All elements in each group must be of the same type.
416246847Sjkim     * The second group can have a count of zero.
417246847Sjkim     *
418246847Sjkim     * Aborts check upon a NULL package element, as this means (at compile
419246847Sjkim     * time) that the remainder of the package elements are also NULL
420246847Sjkim     * (This is the only way to create NULL package elements.)
421246847Sjkim     */
422246847Sjkim    for (i = 0; (i < Count1) && Op; i++)
423246847Sjkim    {
424246847Sjkim        ApCheckObjectType (PredefinedName, Op, Type1, i);
425246847Sjkim        Op = Op->Asl.Next;
426246847Sjkim    }
427246847Sjkim
428246847Sjkim    for (i = 0; (i < Count2) && Op; i++)
429246847Sjkim    {
430246847Sjkim        ApCheckObjectType (PredefinedName, Op, Type2, (i + Count1));
431246847Sjkim        Op = Op->Asl.Next;
432246847Sjkim    }
433246847Sjkim}
434246847Sjkim
435246847Sjkim
436246847Sjkim/*******************************************************************************
437246847Sjkim *
438246847Sjkim * FUNCTION:    ApCheckPackageList
439246847Sjkim *
440246847Sjkim * PARAMETERS:  PredefinedName      - Name of the predefined object
441246847Sjkim *              ParentOp            - Parser op of the parent package
442246847Sjkim *              Package             - Package info for this predefined name
443246847Sjkim *              StartIndex          - Index in parent package where list begins
444246847Sjkim *              ParentCount         - Element count of parent package
445246847Sjkim *
446246847Sjkim * RETURN:      None
447246847Sjkim *
448246847Sjkim * DESCRIPTION: Validate the individual package elements for a predefined name.
449246847Sjkim *              Handles the cases where the predefined name is defined as a
450246847Sjkim *              Package of Packages (subpackages). These are the types:
451246847Sjkim *
452246847Sjkim *              ACPI_PTYPE2
453246847Sjkim *              ACPI_PTYPE2_FIXED
454246847Sjkim *              ACPI_PTYPE2_MIN
455246847Sjkim *              ACPI_PTYPE2_COUNT
456246847Sjkim *              ACPI_PTYPE2_FIX_VAR
457284460Sjkim *              ACPI_PTYPE2_VAR_VAR
458246847Sjkim *
459246847Sjkim ******************************************************************************/
460246847Sjkim
461246847Sjkimstatic void
462246847SjkimApCheckPackageList (
463246847Sjkim    const char                  *PredefinedName,
464246847Sjkim    ACPI_PARSE_OBJECT           *ParentOp,
465246847Sjkim    const ACPI_PREDEFINED_INFO  *Package,
466246847Sjkim    UINT32                      StartIndex,
467246847Sjkim    UINT32                      ParentCount)
468246847Sjkim{
469246847Sjkim    ACPI_PARSE_OBJECT           *SubPackageOp = ParentOp;
470246847Sjkim    ACPI_PARSE_OBJECT           *Op;
471246847Sjkim    ACPI_STATUS                 Status;
472246847Sjkim    UINT32                      Count;
473246847Sjkim    UINT32                      ExpectedCount;
474246847Sjkim    UINT32                      i;
475246847Sjkim    UINT32                      j;
476246847Sjkim
477246847Sjkim
478246847Sjkim    /*
479246847Sjkim     * Validate each subpackage in the parent Package
480246847Sjkim     *
481246847Sjkim     * Note: We ignore NULL package elements on the assumption that
482246847Sjkim     * they will be initialized by the BIOS or other ASL code.
483246847Sjkim     */
484246847Sjkim    for (i = 0; (i < ParentCount) && SubPackageOp; i++)
485246847Sjkim    {
486246847Sjkim        /* Each object in the list must be of type Package */
487246847Sjkim
488246847Sjkim        Status = ApCheckObjectType (PredefinedName, SubPackageOp,
489246847Sjkim            ACPI_RTYPE_PACKAGE, i + StartIndex);
490246847Sjkim        if (ACPI_FAILURE (Status))
491246847Sjkim        {
492246847Sjkim            goto NextSubpackage;
493246847Sjkim        }
494246847Sjkim
495246847Sjkim        /* Examine the different types of expected subpackages */
496246847Sjkim
497246847Sjkim        Op = SubPackageOp->Asl.Child;
498246847Sjkim
499246847Sjkim        /* First child is the package length */
500246847Sjkim
501246847Sjkim        Count = (UINT32) Op->Asl.Value.Integer;
502246847Sjkim        Op = Op->Asl.Next;
503246847Sjkim
504284460Sjkim        /*
505284460Sjkim         * Most subpackage must have at least one element, with
506284460Sjkim         * only rare exceptions. (_RDI)
507284460Sjkim         */
508284460Sjkim        if (!Count &&
509284460Sjkim            (Package->RetInfo.Type != ACPI_PTYPE2_VAR_VAR))
510246847Sjkim        {
511246847Sjkim            ApZeroLengthPackage (PredefinedName, SubPackageOp);
512246847Sjkim            goto NextSubpackage;
513246847Sjkim        }
514246847Sjkim
515246847Sjkim        /*
516246847Sjkim         * Decode the package type.
517246847Sjkim         * PTYPE2 indicates that a "package of packages" is expected for
518246847Sjkim         * this name. The various flavors of PTYPE2 indicate the number
519246847Sjkim         * and format of the subpackages.
520246847Sjkim         */
521246847Sjkim        switch (Package->RetInfo.Type)
522246847Sjkim        {
523246847Sjkim        case ACPI_PTYPE2:
524246847Sjkim        case ACPI_PTYPE2_PKG_COUNT:
525246847Sjkim        case ACPI_PTYPE2_REV_FIXED:
526246847Sjkim
527246847Sjkim            /* Each subpackage has a fixed number of elements */
528246847Sjkim
529246847Sjkim            ExpectedCount = Package->RetInfo.Count1 + Package->RetInfo.Count2;
530246847Sjkim            if (Count < ExpectedCount)
531246847Sjkim            {
532246847Sjkim                ApPackageTooSmall (PredefinedName, SubPackageOp,
533246847Sjkim                    Count, ExpectedCount);
534246847Sjkim                break;
535246847Sjkim            }
536281075Sdim            if (Count > ExpectedCount)
537281075Sdim            {
538281075Sdim                ApPackageTooLarge (PredefinedName, SubPackageOp,
539281075Sdim                    Count, ExpectedCount);
540281075Sdim                break;
541281075Sdim            }
542246847Sjkim
543246847Sjkim            ApCheckPackageElements (PredefinedName, Op,
544246847Sjkim                Package->RetInfo.ObjectType1, Package->RetInfo.Count1,
545246847Sjkim                Package->RetInfo.ObjectType2, Package->RetInfo.Count2);
546246847Sjkim            break;
547246847Sjkim
548246847Sjkim        case ACPI_PTYPE2_FIX_VAR:
549246847Sjkim            /*
550246847Sjkim             * Each subpackage has a fixed number of elements and an
551246847Sjkim             * optional element
552246847Sjkim             */
553246847Sjkim            ExpectedCount = Package->RetInfo.Count1 + Package->RetInfo.Count2;
554246847Sjkim            if (Count < ExpectedCount)
555246847Sjkim            {
556246847Sjkim                ApPackageTooSmall (PredefinedName, SubPackageOp,
557246847Sjkim                    Count, ExpectedCount);
558246847Sjkim                break;
559246847Sjkim            }
560246847Sjkim
561246847Sjkim            ApCheckPackageElements (PredefinedName, Op,
562246847Sjkim                Package->RetInfo.ObjectType1, Package->RetInfo.Count1,
563246847Sjkim                Package->RetInfo.ObjectType2,
564246847Sjkim                Count - Package->RetInfo.Count1);
565246847Sjkim            break;
566246847Sjkim
567284460Sjkim        case ACPI_PTYPE2_VAR_VAR:
568284460Sjkim            /*
569284460Sjkim             * Must have at least the minimum number elements.
570284460Sjkim             * A zero PkgCount means the number of elements is variable.
571284460Sjkim             */
572284460Sjkim            ExpectedCount = Package->RetInfo4.PkgCount;
573284460Sjkim            if (ExpectedCount && (Count < ExpectedCount))
574284460Sjkim            {
575284460Sjkim                ApPackageTooSmall (PredefinedName, SubPackageOp,
576284460Sjkim                    Count, 1);
577284460Sjkim                break;
578284460Sjkim            }
579284460Sjkim
580284460Sjkim            ApCheckPackageElements (PredefinedName, Op,
581284460Sjkim                Package->RetInfo4.SubObjectTypes,
582284460Sjkim                Package->RetInfo4.PkgCount,
583284460Sjkim                0, 0);
584284460Sjkim            break;
585284460Sjkim
586246847Sjkim        case ACPI_PTYPE2_FIXED:
587246847Sjkim
588281075Sdim            /* Each subpackage has a fixed length */
589246847Sjkim
590246847Sjkim            ExpectedCount = Package->RetInfo2.Count;
591246847Sjkim            if (Count < ExpectedCount)
592246847Sjkim            {
593246847Sjkim                ApPackageTooSmall (PredefinedName, SubPackageOp,
594246847Sjkim                    Count, ExpectedCount);
595246847Sjkim                break;
596246847Sjkim            }
597281075Sdim            if (Count > ExpectedCount)
598281075Sdim            {
599281075Sdim                ApPackageTooLarge (PredefinedName, SubPackageOp,
600281075Sdim                    Count, ExpectedCount);
601281075Sdim                break;
602281075Sdim            }
603246847Sjkim
604246847Sjkim            /* Check each object/type combination */
605246847Sjkim
606246847Sjkim            for (j = 0; j < ExpectedCount; j++)
607246847Sjkim            {
608246847Sjkim                ApCheckObjectType (PredefinedName, Op,
609246847Sjkim                    Package->RetInfo2.ObjectType[j], j);
610246847Sjkim
611246847Sjkim                Op = Op->Asl.Next;
612246847Sjkim            }
613246847Sjkim            break;
614246847Sjkim
615246847Sjkim        case ACPI_PTYPE2_MIN:
616246847Sjkim
617281075Sdim            /* Each subpackage has a variable but minimum length */
618246847Sjkim
619246847Sjkim            ExpectedCount = Package->RetInfo.Count1;
620246847Sjkim            if (Count < ExpectedCount)
621246847Sjkim            {
622246847Sjkim                ApPackageTooSmall (PredefinedName, SubPackageOp,
623246847Sjkim                    Count, ExpectedCount);
624246847Sjkim                break;
625246847Sjkim            }
626246847Sjkim
627281075Sdim            /* Check the type of each subpackage element */
628246847Sjkim
629246847Sjkim            ApCheckPackageElements (PredefinedName, Op,
630246847Sjkim                Package->RetInfo.ObjectType1, Count, 0, 0);
631246847Sjkim            break;
632246847Sjkim
633246847Sjkim        case ACPI_PTYPE2_COUNT:
634246847Sjkim            /*
635246847Sjkim             * First element is the (Integer) count of elements, including
636246847Sjkim             * the count field (the ACPI name is NumElements)
637246847Sjkim             */
638246847Sjkim            Status = ApCheckObjectType (PredefinedName, Op,
639246847Sjkim                ACPI_RTYPE_INTEGER, 0);
640246847Sjkim
641246847Sjkim            /* We must have an integer count from above (otherwise, use Count) */
642246847Sjkim
643246847Sjkim            if (ACPI_SUCCESS (Status))
644246847Sjkim            {
645246847Sjkim                /*
646246847Sjkim                 * Make sure package is large enough for the Count and is
647246847Sjkim                 * is as large as the minimum size
648246847Sjkim                 */
649246847Sjkim                ExpectedCount = (UINT32) Op->Asl.Value.Integer;
650246847Sjkim
651246847Sjkim                if (Count < ExpectedCount)
652246847Sjkim                {
653246847Sjkim                    ApPackageTooSmall (PredefinedName, SubPackageOp,
654246847Sjkim                        Count, ExpectedCount);
655246847Sjkim                    break;
656246847Sjkim                }
657246847Sjkim                else if (Count > ExpectedCount)
658246847Sjkim                {
659246847Sjkim                    ApPackageTooLarge (PredefinedName, SubPackageOp,
660246847Sjkim                        Count, ExpectedCount);
661246847Sjkim                }
662246847Sjkim
663246847Sjkim                /* Some names of this type have a minimum length */
664246847Sjkim
665246847Sjkim                if (Count < Package->RetInfo.Count1)
666246847Sjkim                {
667246847Sjkim                    ExpectedCount = Package->RetInfo.Count1;
668246847Sjkim                    ApPackageTooSmall (PredefinedName, SubPackageOp,
669246847Sjkim                        Count, ExpectedCount);
670246847Sjkim                    break;
671246847Sjkim                }
672246847Sjkim
673246847Sjkim                Count = ExpectedCount;
674246847Sjkim            }
675246847Sjkim
676281075Sdim            /* Check the type of each subpackage element */
677246847Sjkim
678246847Sjkim            Op = Op->Asl.Next;
679246847Sjkim            ApCheckPackageElements (PredefinedName, Op,
680246847Sjkim                Package->RetInfo.ObjectType1, (Count - 1), 0, 0);
681246847Sjkim            break;
682246847Sjkim
683246847Sjkim        default:
684246847Sjkim            break;
685246847Sjkim        }
686246847Sjkim
687246847SjkimNextSubpackage:
688246847Sjkim        SubPackageOp = SubPackageOp->Asl.Next;
689246847Sjkim    }
690246847Sjkim}
691246847Sjkim
692246847Sjkim
693246847Sjkim/*******************************************************************************
694246847Sjkim *
695246847Sjkim * FUNCTION:    ApPackageTooSmall
696246847Sjkim *
697246847Sjkim * PARAMETERS:  PredefinedName      - Name of the predefined object
698246847Sjkim *              Op                  - Current parser op
699246847Sjkim *              Count               - Actual package element count
700246847Sjkim *              ExpectedCount       - Expected package element count
701246847Sjkim *
702246847Sjkim * RETURN:      None
703246847Sjkim *
704246847Sjkim * DESCRIPTION: Issue error message for a package that is smaller than
705246847Sjkim *              required.
706246847Sjkim *
707246847Sjkim ******************************************************************************/
708246847Sjkim
709246847Sjkimstatic void
710246847SjkimApPackageTooSmall (
711246847Sjkim    const char                  *PredefinedName,
712246847Sjkim    ACPI_PARSE_OBJECT           *Op,
713246847Sjkim    UINT32                      Count,
714246847Sjkim    UINT32                      ExpectedCount)
715246847Sjkim{
716246847Sjkim
717246847Sjkim    sprintf (MsgBuffer, "%s: length %u, required minimum is %u",
718246847Sjkim        PredefinedName, Count, ExpectedCount);
719246847Sjkim
720246847Sjkim    AslError (ASL_ERROR, ASL_MSG_RESERVED_PACKAGE_LENGTH, Op, MsgBuffer);
721246847Sjkim}
722246847Sjkim
723246847Sjkim
724246847Sjkim/*******************************************************************************
725246847Sjkim *
726246847Sjkim * FUNCTION:    ApZeroLengthPackage
727246847Sjkim *
728246847Sjkim * PARAMETERS:  PredefinedName      - Name of the predefined object
729246847Sjkim *              Op                  - Current parser op
730246847Sjkim *
731246847Sjkim * RETURN:      None
732246847Sjkim *
733246847Sjkim * DESCRIPTION: Issue error message for a zero-length package (a package that
734246847Sjkim *              is required to have a non-zero length). Variable length
735246847Sjkim *              packages seem to be allowed to have zero length, however.
736246847Sjkim *              Even if not allowed, BIOS code does it.
737246847Sjkim *
738246847Sjkim ******************************************************************************/
739246847Sjkim
740246847Sjkimstatic void
741246847SjkimApZeroLengthPackage (
742246847Sjkim    const char                  *PredefinedName,
743246847Sjkim    ACPI_PARSE_OBJECT           *Op)
744246847Sjkim{
745246847Sjkim
746246847Sjkim    sprintf (MsgBuffer, "%s: length is zero", PredefinedName);
747246847Sjkim
748246847Sjkim    AslError (ASL_ERROR, ASL_MSG_RESERVED_PACKAGE_LENGTH, Op, MsgBuffer);
749246847Sjkim}
750246847Sjkim
751246847Sjkim
752246847Sjkim/*******************************************************************************
753246847Sjkim *
754246847Sjkim * FUNCTION:    ApPackageTooLarge
755246847Sjkim *
756246847Sjkim * PARAMETERS:  PredefinedName      - Name of the predefined object
757246847Sjkim *              Op                  - Current parser op
758246847Sjkim *              Count               - Actual package element count
759246847Sjkim *              ExpectedCount       - Expected package element count
760246847Sjkim *
761246847Sjkim * RETURN:      None
762246847Sjkim *
763246847Sjkim * DESCRIPTION: Issue a remark for a package that is larger than expected.
764246847Sjkim *
765246847Sjkim ******************************************************************************/
766246847Sjkim
767246847Sjkimstatic void
768246847SjkimApPackageTooLarge (
769246847Sjkim    const char                  *PredefinedName,
770246847Sjkim    ACPI_PARSE_OBJECT           *Op,
771246847Sjkim    UINT32                      Count,
772246847Sjkim    UINT32                      ExpectedCount)
773246847Sjkim{
774246847Sjkim
775246847Sjkim    sprintf (MsgBuffer, "%s: length is %u, only %u required",
776246847Sjkim        PredefinedName, Count, ExpectedCount);
777246847Sjkim
778246847Sjkim    AslError (ASL_REMARK, ASL_MSG_RESERVED_PACKAGE_LENGTH, Op, MsgBuffer);
779246847Sjkim}
780