1 /******************************************************************************
3 * Module Name: aslprepkg - support for ACPI predefined name package objects
5 *****************************************************************************/
8 * Copyright (C) 2000 - 2016, Intel Corp.
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions, and the following disclaimer,
16 * without modification.
17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18 * substantially similar to the "NO WARRANTY" disclaimer below
19 * ("Disclaimer") and any redistribution must be conditioned upon
20 * including a substantially similar Disclaimer requirement for further
21 * binary redistribution.
22 * 3. Neither the names of the above-listed copyright holders nor the names
23 * of any contributors may be used to endorse or promote products derived
24 * from this software without specific prior written permission.
26 * Alternatively, this software may be distributed under the terms of the
27 * GNU General Public License ("GPL") version 2 as published by the Free
28 * Software Foundation.
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41 * POSSIBILITY OF SUCH DAMAGES.
44 #include <contrib/dev/acpica/compiler/aslcompiler.h>
45 #include "aslcompiler.y.h"
46 #include <contrib/dev/acpica/include/acpredef.h>
49 #define _COMPONENT ACPI_COMPILER
50 ACPI_MODULE_NAME ("aslprepkg")
53 /* Local prototypes */
55 static ACPI_PARSE_OBJECT *
56 ApCheckPackageElements (
57 const char *PredefinedName,
58 ACPI_PARSE_OBJECT *Op,
66 const char *PredefinedName,
67 ACPI_PARSE_OBJECT *ParentOp,
68 const ACPI_PREDEFINED_INFO *Package,
74 const char *PredefinedName,
75 ACPI_PARSE_OBJECT *Op,
77 UINT32 ExpectedCount);
81 const char *PredefinedName,
82 ACPI_PARSE_OBJECT *Op);
86 const char *PredefinedName,
87 ACPI_PARSE_OBJECT *Op,
89 UINT32 ExpectedCount);
93 ACPI_PARSE_OBJECT *ParentOp,
94 const ACPI_PREDEFINED_INFO *Predefined);
97 /*******************************************************************************
99 * FUNCTION: ApCheckPackage
101 * PARAMETERS: ParentOp - Parser op for the package
102 * Predefined - Pointer to package-specific info for
107 * DESCRIPTION: Top-level validation for predefined name return package
110 ******************************************************************************/
114 ACPI_PARSE_OBJECT *ParentOp,
115 const ACPI_PREDEFINED_INFO *Predefined)
117 ACPI_PARSE_OBJECT *Op;
118 const ACPI_PREDEFINED_INFO *Package;
120 UINT32 ExpectedCount;
125 /* The package info for this name is in the next table entry */
127 Package = Predefined + 1;
129 /* First child is the package length */
131 Op = ParentOp->Asl.Child;
132 Count = (UINT32) Op->Asl.Value.Integer;
135 * Many of the variable-length top-level packages are allowed to simply
136 * have zero elements. This allows the BIOS to tell the host that even
137 * though the predefined name/method exists, the feature is not supported.
138 * Other package types require one or more elements. In any case, there
139 * is no need to continue validation.
143 switch (Package->RetInfo.Type)
145 case ACPI_PTYPE1_FIXED:
146 case ACPI_PTYPE1_OPTION:
147 case ACPI_PTYPE2_PKG_COUNT:
148 case ACPI_PTYPE2_REV_FIXED:
150 ApZeroLengthPackage (Predefined->Info.Name, ParentOp);
153 case ACPI_PTYPE1_VAR:
155 case ACPI_PTYPE2_COUNT:
156 case ACPI_PTYPE2_FIXED:
157 case ACPI_PTYPE2_MIN:
158 case ACPI_PTYPE2_FIX_VAR:
159 case ACPI_PTYPE2_VAR_VAR:
168 /* Get the first element of the package */
172 /* Decode the package type */
174 switch (Package->RetInfo.Type)
176 case ACPI_PTYPE_CUSTOM:
178 ApCustomPackage (ParentOp, Predefined);
181 case ACPI_PTYPE1_FIXED:
183 * The package count is fixed and there are no subpackages
185 * If package is too small, exit.
186 * If package is larger than expected, issue warning but continue
188 ExpectedCount = Package->RetInfo.Count1 + Package->RetInfo.Count2;
189 if (Count < ExpectedCount)
191 goto PackageTooSmall;
193 else if (Count > ExpectedCount)
195 ApPackageTooLarge (Predefined->Info.Name, ParentOp,
196 Count, ExpectedCount);
199 /* Validate all elements of the package */
201 ApCheckPackageElements (Predefined->Info.Name, Op,
202 Package->RetInfo.ObjectType1, Package->RetInfo.Count1,
203 Package->RetInfo.ObjectType2, Package->RetInfo.Count2);
206 case ACPI_PTYPE1_VAR:
208 * The package count is variable, there are no subpackages,
209 * and all elements must be of the same type
211 for (i = 0; i < Count; i++)
213 ApCheckObjectType (Predefined->Info.Name, Op,
214 Package->RetInfo.ObjectType1, i);
219 case ACPI_PTYPE1_OPTION:
221 * The package count is variable, there are no subpackages.
222 * There are a fixed number of required elements, and a variable
223 * number of optional elements.
225 * Check if package is at least as large as the minimum required
227 ExpectedCount = Package->RetInfo3.Count;
228 if (Count < ExpectedCount)
230 goto PackageTooSmall;
233 /* Variable number of sub-objects */
235 for (i = 0; i < Count; i++)
237 if (i < Package->RetInfo3.Count)
239 /* These are the required package elements (0, 1, or 2) */
241 ApCheckObjectType (Predefined->Info.Name, Op,
242 Package->RetInfo3.ObjectType[i], i);
246 /* These are the optional package elements */
248 ApCheckObjectType (Predefined->Info.Name, Op,
249 Package->RetInfo3.TailObjectType, i);
256 case ACPI_PTYPE2_REV_FIXED:
258 /* First element is the (Integer) revision */
260 ApCheckObjectType (Predefined->Info.Name, Op,
261 ACPI_RTYPE_INTEGER, 0);
266 /* Examine the subpackages */
268 ApCheckPackageList (Predefined->Info.Name, Op,
272 case ACPI_PTYPE2_PKG_COUNT:
274 /* First element is the (Integer) count of subpackages to follow */
276 Status = ApCheckObjectType (Predefined->Info.Name, Op,
277 ACPI_RTYPE_INTEGER, 0);
279 /* We must have an integer count from above (otherwise, use Count) */
281 if (ACPI_SUCCESS (Status))
284 * Count cannot be larger than the parent package length, but
285 * allow it to be smaller. The >= accounts for the Integer above.
287 ExpectedCount = (UINT32) Op->Asl.Value.Integer;
288 if (ExpectedCount >= Count)
290 goto PackageTooSmall;
293 Count = ExpectedCount;
298 /* Examine the subpackages */
300 ApCheckPackageList (Predefined->Info.Name, Op,
304 case ACPI_PTYPE2_UUID_PAIR:
306 /* The package contains a variable list of UUID Buffer/Package pairs */
308 /* The length of the package must be even */
312 sprintf (MsgBuffer, "%4.4s: Package length, %d, must be even.",
313 Predefined->Info.Name, Count);
315 AslError (ASL_ERROR, ASL_MSG_RESERVED_PACKAGE_LENGTH,
316 ParentOp->Asl.Child, MsgBuffer);
319 /* Validate the alternating types */
321 for (i = 0; i < Count; ++i)
325 ApCheckObjectType (Predefined->Info.Name, Op,
326 Package->RetInfo.ObjectType2, i);
330 ApCheckObjectType (Predefined->Info.Name, Op,
331 Package->RetInfo.ObjectType1, i);
339 case ACPI_PTYPE2_VAR_VAR:
341 /* Check for minimum size (ints at beginning + 1 subpackage) */
343 ExpectedCount = Package->RetInfo4.Count1 + 1;
344 if (Count < ExpectedCount)
346 goto PackageTooSmall;
349 /* Check the non-package elements at beginning of main package */
351 for (i = 0; i < Package->RetInfo4.Count1; ++i)
353 Status = ApCheckObjectType (Predefined->Info.Name, Op,
354 Package->RetInfo4.ObjectType1, i);
358 /* Examine the variable-length list of subpackages */
360 ApCheckPackageList (Predefined->Info.Name, Op,
361 Package, Package->RetInfo4.Count1, Count);
366 case ACPI_PTYPE2_FIXED:
367 case ACPI_PTYPE2_MIN:
368 case ACPI_PTYPE2_COUNT:
369 case ACPI_PTYPE2_FIX_VAR:
371 * These types all return a single Package that consists of a
372 * variable number of subpackages.
375 /* Examine the subpackages */
377 ApCheckPackageList (Predefined->Info.Name, Op,
388 ApPackageTooSmall (Predefined->Info.Name, ParentOp,
389 Count, ExpectedCount);
393 /*******************************************************************************
395 * FUNCTION: ApCustomPackage
397 * PARAMETERS: ParentOp - Parse op for the package
398 * Predefined - Pointer to package-specific info for
403 * DESCRIPTION: Validate packages that don't fit into the standard model and
404 * require custom code.
406 * NOTE: Currently used for the _BIX method only. When needed for two or more
407 * methods, probably a detect/dispatch mechanism will be required.
409 ******************************************************************************/
413 ACPI_PARSE_OBJECT *ParentOp,
414 const ACPI_PREDEFINED_INFO *Predefined)
416 ACPI_PARSE_OBJECT *Op;
418 UINT32 ExpectedCount;
422 /* First child is the package length */
424 Op = ParentOp->Asl.Child;
425 Count = (UINT32) Op->Asl.Value.Integer;
427 /* Get the version number, must be Integer */
430 Version = (UINT32) Op->Asl.Value.Integer;
431 if (Op->Asl.ParseOpcode != PARSEOP_INTEGER)
433 AslError (ASL_ERROR, ASL_MSG_RESERVED_OPERAND_TYPE, Op, MsgBuffer);
437 /* Validate count (# of elements) */
439 ExpectedCount = 21; /* Version 1 */
442 ExpectedCount = 20; /* Version 0 */
445 if (Count < ExpectedCount)
447 ApPackageTooSmall (Predefined->Info.Name, ParentOp,
448 Count, ExpectedCount);
451 else if (Count > ExpectedCount)
453 ApPackageTooLarge (Predefined->Info.Name, ParentOp,
454 Count, ExpectedCount);
457 /* Validate all elements of the package */
459 Op = ApCheckPackageElements (Predefined->Info.Name, Op,
460 ACPI_RTYPE_INTEGER, 16,
461 ACPI_RTYPE_STRING, 4);
463 /* Version 1 has a single trailing integer */
467 ApCheckPackageElements (Predefined->Info.Name, Op,
468 ACPI_RTYPE_INTEGER, 1, 0, 0);
473 /*******************************************************************************
475 * FUNCTION: ApCheckPackageElements
477 * PARAMETERS: PredefinedName - Name of the predefined object
478 * Op - Parser op for the package
479 * Type1 - Object type for first group
480 * Count1 - Count for first group
481 * Type2 - Object type for second group
482 * Count2 - Count for second group
484 * RETURN: Next Op peer in the parse tree, after all specified elements
485 * have been validated. Used for multiple validations (calls
488 * DESCRIPTION: Validate all elements of a package. Works with packages that
489 * are defined to contain up to two groups of different object
492 ******************************************************************************/
494 static ACPI_PARSE_OBJECT *
495 ApCheckPackageElements (
496 const char *PredefinedName,
497 ACPI_PARSE_OBJECT *Op,
507 * Up to two groups of package elements are supported by the data
508 * structure. All elements in each group must be of the same type.
509 * The second group can have a count of zero.
511 * Aborts check upon a NULL package element, as this means (at compile
512 * time) that the remainder of the package elements are also NULL
513 * (This is the only way to create NULL package elements.)
515 for (i = 0; (i < Count1) && Op; i++)
517 ApCheckObjectType (PredefinedName, Op, Type1, i);
521 for (i = 0; (i < Count2) && Op; i++)
523 ApCheckObjectType (PredefinedName, Op, Type2, (i + Count1));
531 /*******************************************************************************
533 * FUNCTION: ApCheckPackageList
535 * PARAMETERS: PredefinedName - Name of the predefined object
536 * ParentOp - Parser op of the parent package
537 * Package - Package info for this predefined name
538 * StartIndex - Index in parent package where list begins
539 * ParentCount - Element count of parent package
543 * DESCRIPTION: Validate the individual package elements for a predefined name.
544 * Handles the cases where the predefined name is defined as a
545 * Package of Packages (subpackages). These are the types:
551 * ACPI_PTYPE2_FIX_VAR
552 * ACPI_PTYPE2_VAR_VAR
554 ******************************************************************************/
558 const char *PredefinedName,
559 ACPI_PARSE_OBJECT *ParentOp,
560 const ACPI_PREDEFINED_INFO *Package,
564 ACPI_PARSE_OBJECT *SubPackageOp = ParentOp;
565 ACPI_PARSE_OBJECT *Op;
568 UINT32 ExpectedCount;
574 * Validate each subpackage in the parent Package
576 * Note: We ignore NULL package elements on the assumption that
577 * they will be initialized by the BIOS or other ASL code.
579 for (i = 0; (i < ParentCount) && SubPackageOp; i++)
581 /* Each object in the list must be of type Package */
583 Status = ApCheckObjectType (PredefinedName, SubPackageOp,
584 ACPI_RTYPE_PACKAGE, i + StartIndex);
585 if (ACPI_FAILURE (Status))
590 /* Examine the different types of expected subpackages */
592 Op = SubPackageOp->Asl.Child;
594 /* First child is the package length */
596 Count = (UINT32) Op->Asl.Value.Integer;
600 * Most subpackage must have at least one element, with
601 * only rare exceptions. (_RDI)
604 (Package->RetInfo.Type != ACPI_PTYPE2_VAR_VAR))
606 ApZeroLengthPackage (PredefinedName, SubPackageOp);
611 * Decode the package type.
612 * PTYPE2 indicates that a "package of packages" is expected for
613 * this name. The various flavors of PTYPE2 indicate the number
614 * and format of the subpackages.
616 switch (Package->RetInfo.Type)
619 case ACPI_PTYPE2_PKG_COUNT:
620 case ACPI_PTYPE2_REV_FIXED:
622 /* Each subpackage has a fixed number of elements */
624 ExpectedCount = Package->RetInfo.Count1 + Package->RetInfo.Count2;
625 if (Count < ExpectedCount)
627 ApPackageTooSmall (PredefinedName, SubPackageOp,
628 Count, ExpectedCount);
631 if (Count > ExpectedCount)
633 ApPackageTooLarge (PredefinedName, SubPackageOp,
634 Count, ExpectedCount);
638 ApCheckPackageElements (PredefinedName, Op,
639 Package->RetInfo.ObjectType1, Package->RetInfo.Count1,
640 Package->RetInfo.ObjectType2, Package->RetInfo.Count2);
643 case ACPI_PTYPE2_FIX_VAR:
645 * Each subpackage has a fixed number of elements and an
648 ExpectedCount = Package->RetInfo.Count1 + Package->RetInfo.Count2;
649 if (Count < ExpectedCount)
651 ApPackageTooSmall (PredefinedName, SubPackageOp,
652 Count, ExpectedCount);
656 ApCheckPackageElements (PredefinedName, Op,
657 Package->RetInfo.ObjectType1, Package->RetInfo.Count1,
658 Package->RetInfo.ObjectType2,
659 Count - Package->RetInfo.Count1);
662 case ACPI_PTYPE2_VAR_VAR:
664 * Must have at least the minimum number elements.
665 * A zero PkgCount means the number of elements is variable.
667 ExpectedCount = Package->RetInfo4.PkgCount;
668 if (ExpectedCount && (Count < ExpectedCount))
670 ApPackageTooSmall (PredefinedName, SubPackageOp,
675 ApCheckPackageElements (PredefinedName, Op,
676 Package->RetInfo4.SubObjectTypes,
677 Package->RetInfo4.PkgCount,
681 case ACPI_PTYPE2_FIXED:
683 /* Each subpackage has a fixed length */
685 ExpectedCount = Package->RetInfo2.Count;
686 if (Count < ExpectedCount)
688 ApPackageTooSmall (PredefinedName, SubPackageOp,
689 Count, ExpectedCount);
692 if (Count > ExpectedCount)
694 ApPackageTooLarge (PredefinedName, SubPackageOp,
695 Count, ExpectedCount);
699 /* Check each object/type combination */
701 for (j = 0; j < ExpectedCount; j++)
703 ApCheckObjectType (PredefinedName, Op,
704 Package->RetInfo2.ObjectType[j], j);
710 case ACPI_PTYPE2_MIN:
712 /* Each subpackage has a variable but minimum length */
714 ExpectedCount = Package->RetInfo.Count1;
715 if (Count < ExpectedCount)
717 ApPackageTooSmall (PredefinedName, SubPackageOp,
718 Count, ExpectedCount);
722 /* Check the type of each subpackage element */
724 ApCheckPackageElements (PredefinedName, Op,
725 Package->RetInfo.ObjectType1, Count, 0, 0);
728 case ACPI_PTYPE2_COUNT:
730 * First element is the (Integer) count of elements, including
731 * the count field (the ACPI name is NumElements)
733 Status = ApCheckObjectType (PredefinedName, Op,
734 ACPI_RTYPE_INTEGER, 0);
736 /* We must have an integer count from above (otherwise, use Count) */
738 if (ACPI_SUCCESS (Status))
741 * Make sure package is large enough for the Count and is
742 * is as large as the minimum size
744 ExpectedCount = (UINT32) Op->Asl.Value.Integer;
746 if (Count < ExpectedCount)
748 ApPackageTooSmall (PredefinedName, SubPackageOp,
749 Count, ExpectedCount);
752 else if (Count > ExpectedCount)
754 ApPackageTooLarge (PredefinedName, SubPackageOp,
755 Count, ExpectedCount);
758 /* Some names of this type have a minimum length */
760 if (Count < Package->RetInfo.Count1)
762 ExpectedCount = Package->RetInfo.Count1;
763 ApPackageTooSmall (PredefinedName, SubPackageOp,
764 Count, ExpectedCount);
768 Count = ExpectedCount;
771 /* Check the type of each subpackage element */
774 ApCheckPackageElements (PredefinedName, Op,
775 Package->RetInfo.ObjectType1, (Count - 1), 0, 0);
783 SubPackageOp = SubPackageOp->Asl.Next;
788 /*******************************************************************************
790 * FUNCTION: ApPackageTooSmall
792 * PARAMETERS: PredefinedName - Name of the predefined object
793 * Op - Current parser op
794 * Count - Actual package element count
795 * ExpectedCount - Expected package element count
799 * DESCRIPTION: Issue error message for a package that is smaller than
802 ******************************************************************************/
806 const char *PredefinedName,
807 ACPI_PARSE_OBJECT *Op,
809 UINT32 ExpectedCount)
812 sprintf (MsgBuffer, "%s: length %u, required minimum is %u",
813 PredefinedName, Count, ExpectedCount);
815 AslError (ASL_ERROR, ASL_MSG_RESERVED_PACKAGE_LENGTH, Op, MsgBuffer);
819 /*******************************************************************************
821 * FUNCTION: ApZeroLengthPackage
823 * PARAMETERS: PredefinedName - Name of the predefined object
824 * Op - Current parser op
828 * DESCRIPTION: Issue error message for a zero-length package (a package that
829 * is required to have a non-zero length). Variable length
830 * packages seem to be allowed to have zero length, however.
831 * Even if not allowed, BIOS code does it.
833 ******************************************************************************/
836 ApZeroLengthPackage (
837 const char *PredefinedName,
838 ACPI_PARSE_OBJECT *Op)
841 sprintf (MsgBuffer, "%s: length is zero", PredefinedName);
843 AslError (ASL_ERROR, ASL_MSG_RESERVED_PACKAGE_LENGTH, Op, MsgBuffer);
847 /*******************************************************************************
849 * FUNCTION: ApPackageTooLarge
851 * PARAMETERS: PredefinedName - Name of the predefined object
852 * Op - Current parser op
853 * Count - Actual package element count
854 * ExpectedCount - Expected package element count
858 * DESCRIPTION: Issue a remark for a package that is larger than expected.
860 ******************************************************************************/
864 const char *PredefinedName,
865 ACPI_PARSE_OBJECT *Op,
867 UINT32 ExpectedCount)
870 sprintf (MsgBuffer, "%s: length is %u, only %u required",
871 PredefinedName, Count, ExpectedCount);
873 AslError (ASL_REMARK, ASL_MSG_RESERVED_PACKAGE_LENGTH, Op, MsgBuffer);