The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/contrib/dev/acpica/compiler/aslprepkg.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /******************************************************************************
    2  *
    3  * Module Name: aslprepkg - support for ACPI predefined name package objects
    4  *
    5  *****************************************************************************/
    6 
    7 /******************************************************************************
    8  *
    9  * 1. Copyright Notice
   10  *
   11  * Some or all of this work - Copyright (c) 1999 - 2022, Intel Corp.
   12  * All rights reserved.
   13  *
   14  * 2. License
   15  *
   16  * 2.1. This is your license from Intel Corp. under its intellectual property
   17  * rights. You may have additional license terms from the party that provided
   18  * you this software, covering your right to use that party's intellectual
   19  * property rights.
   20  *
   21  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
   22  * copy of the source code appearing in this file ("Covered Code") an
   23  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
   24  * base code distributed originally by Intel ("Original Intel Code") to copy,
   25  * make derivatives, distribute, use and display any portion of the Covered
   26  * Code in any form, with the right to sublicense such rights; and
   27  *
   28  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
   29  * license (with the right to sublicense), under only those claims of Intel
   30  * patents that are infringed by the Original Intel Code, to make, use, sell,
   31  * offer to sell, and import the Covered Code and derivative works thereof
   32  * solely to the minimum extent necessary to exercise the above copyright
   33  * license, and in no event shall the patent license extend to any additions
   34  * to or modifications of the Original Intel Code. No other license or right
   35  * is granted directly or by implication, estoppel or otherwise;
   36  *
   37  * The above copyright and patent license is granted only if the following
   38  * conditions are met:
   39  *
   40  * 3. Conditions
   41  *
   42  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
   43  * Redistribution of source code of any substantial portion of the Covered
   44  * Code or modification with rights to further distribute source must include
   45  * the above Copyright Notice, the above License, this list of Conditions,
   46  * and the following Disclaimer and Export Compliance provision. In addition,
   47  * Licensee must cause all Covered Code to which Licensee contributes to
   48  * contain a file documenting the changes Licensee made to create that Covered
   49  * Code and the date of any change. Licensee must include in that file the
   50  * documentation of any changes made by any predecessor Licensee. Licensee
   51  * must include a prominent statement that the modification is derived,
   52  * directly or indirectly, from Original Intel Code.
   53  *
   54  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
   55  * Redistribution of source code of any substantial portion of the Covered
   56  * Code or modification without rights to further distribute source must
   57  * include the following Disclaimer and Export Compliance provision in the
   58  * documentation and/or other materials provided with distribution. In
   59  * addition, Licensee may not authorize further sublicense of source of any
   60  * portion of the Covered Code, and must include terms to the effect that the
   61  * license from Licensee to its licensee is limited to the intellectual
   62  * property embodied in the software Licensee provides to its licensee, and
   63  * not to intellectual property embodied in modifications its licensee may
   64  * make.
   65  *
   66  * 3.3. Redistribution of Executable. Redistribution in executable form of any
   67  * substantial portion of the Covered Code or modification must reproduce the
   68  * above Copyright Notice, and the following Disclaimer and Export Compliance
   69  * provision in the documentation and/or other materials provided with the
   70  * distribution.
   71  *
   72  * 3.4. Intel retains all right, title, and interest in and to the Original
   73  * Intel Code.
   74  *
   75  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
   76  * Intel shall be used in advertising or otherwise to promote the sale, use or
   77  * other dealings in products derived from or relating to the Covered Code
   78  * without prior written authorization from Intel.
   79  *
   80  * 4. Disclaimer and Export Compliance
   81  *
   82  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
   83  * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
   84  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
   85  * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
   86  * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
   87  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
   88  * PARTICULAR PURPOSE.
   89  *
   90  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
   91  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
   92  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
   93  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
   94  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
   95  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
   96  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
   97  * LIMITED REMEDY.
   98  *
   99  * 4.3. Licensee shall not export, either directly or indirectly, any of this
  100  * software or system incorporating such software without first obtaining any
  101  * required license or other approval from the U. S. Department of Commerce or
  102  * any other agency or department of the United States Government. In the
  103  * event Licensee exports any such software from the United States or
  104  * re-exports any such software from a foreign destination, Licensee shall
  105  * ensure that the distribution and export/re-export of the software is in
  106  * compliance with all laws, regulations, orders, or other restrictions of the
  107  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
  108  * any of its subsidiaries will export/re-export any technical data, process,
  109  * software, or service, directly or indirectly, to any country for which the
  110  * United States government or any agency thereof requires an export license,
  111  * other governmental approval, or letter of assurance, without first obtaining
  112  * such license, approval or letter.
  113  *
  114  *****************************************************************************
  115  *
  116  * Alternatively, you may choose to be licensed under the terms of the
  117  * following license:
  118  *
  119  * Redistribution and use in source and binary forms, with or without
  120  * modification, are permitted provided that the following conditions
  121  * are met:
  122  * 1. Redistributions of source code must retain the above copyright
  123  *    notice, this list of conditions, and the following disclaimer,
  124  *    without modification.
  125  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
  126  *    substantially similar to the "NO WARRANTY" disclaimer below
  127  *    ("Disclaimer") and any redistribution must be conditioned upon
  128  *    including a substantially similar Disclaimer requirement for further
  129  *    binary redistribution.
  130  * 3. Neither the names of the above-listed copyright holders nor the names
  131  *    of any contributors may be used to endorse or promote products derived
  132  *    from this software without specific prior written permission.
  133  *
  134  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  135  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  136  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  137  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  138  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  139  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  140  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  141  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  142  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  143  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  144  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  145  *
  146  * Alternatively, you may choose to be licensed under the terms of the
  147  * GNU General Public License ("GPL") version 2 as published by the Free
  148  * Software Foundation.
  149  *
  150  *****************************************************************************/
  151 
  152 #include <contrib/dev/acpica/compiler/aslcompiler.h>
  153 #include "aslcompiler.y.h"
  154 #include <contrib/dev/acpica/include/acpredef.h>
  155 
  156 
  157 #define _COMPONENT          ACPI_COMPILER
  158         ACPI_MODULE_NAME    ("aslprepkg")
  159 
  160 
  161 /* Local prototypes */
  162 
  163 static ACPI_PARSE_OBJECT *
  164 ApCheckPackageElements (
  165     const char                  *PredefinedName,
  166     ACPI_PARSE_OBJECT           *Op,
  167     UINT8                       Type1,
  168     UINT32                      Count1,
  169     UINT8                       Type2,
  170     UINT32                      Count2);
  171 
  172 static void
  173 ApCheckPackageList (
  174     const char                  *PredefinedName,
  175     ACPI_PARSE_OBJECT           *ParentOp,
  176     const ACPI_PREDEFINED_INFO  *Package,
  177     UINT32                      StartIndex,
  178     UINT32                      Count);
  179 
  180 static void
  181 ApPackageTooSmall (
  182     const char                  *PredefinedName,
  183     ACPI_PARSE_OBJECT           *Op,
  184     UINT32                      Count,
  185     UINT32                      ExpectedCount);
  186 
  187 static void
  188 ApZeroLengthPackage (
  189     const char                  *PredefinedName,
  190     ACPI_PARSE_OBJECT           *Op);
  191 
  192 static void
  193 ApPackageTooLarge (
  194     const char                  *PredefinedName,
  195     ACPI_PARSE_OBJECT           *Op,
  196     UINT32                      Count,
  197     UINT32                      ExpectedCount);
  198 
  199 static void
  200 ApCustomPackage (
  201     ACPI_PARSE_OBJECT           *ParentOp,
  202     const ACPI_PREDEFINED_INFO  *Predefined);
  203 
  204 
  205 /*******************************************************************************
  206  *
  207  * FUNCTION:    ApCheckPackage
  208  *
  209  * PARAMETERS:  ParentOp            - Parser op for the package
  210  *              Predefined          - Pointer to package-specific info for
  211  *                                    the method
  212  *
  213  * RETURN:      None
  214  *
  215  * DESCRIPTION: Top-level validation for predefined name return package
  216  *              objects.
  217  *
  218  ******************************************************************************/
  219 
  220 void
  221 ApCheckPackage (
  222     ACPI_PARSE_OBJECT           *ParentOp,
  223     const ACPI_PREDEFINED_INFO  *Predefined)
  224 {
  225     ACPI_PARSE_OBJECT           *Op;
  226     const ACPI_PREDEFINED_INFO  *Package;
  227     ACPI_STATUS                 Status;
  228     UINT32                      ExpectedCount;
  229     UINT32                      Count;
  230     UINT32                      i;
  231 
  232 
  233     /* The package info for this name is in the next table entry */
  234 
  235     Package = Predefined + 1;
  236 
  237     /* First child is the package length */
  238 
  239     Op = ParentOp->Asl.Child;
  240     Count = (UINT32) Op->Asl.Value.Integer;
  241 
  242     /*
  243      * Many of the variable-length top-level packages are allowed to simply
  244      * have zero elements. This allows the BIOS to tell the host that even
  245      * though the predefined name/method exists, the feature is not supported.
  246      * Other package types require one or more elements. In any case, there
  247      * is no need to continue validation.
  248      */
  249     if (!Count)
  250     {
  251         switch (Package->RetInfo.Type)
  252         {
  253         case ACPI_PTYPE1_FIXED:
  254         case ACPI_PTYPE1_OPTION:
  255         case ACPI_PTYPE2_PKG_COUNT:
  256         case ACPI_PTYPE2_REV_FIXED:
  257 
  258             ApZeroLengthPackage (Predefined->Info.Name, ParentOp);
  259             break;
  260 
  261         case ACPI_PTYPE1_VAR:
  262         case ACPI_PTYPE2:
  263         case ACPI_PTYPE2_COUNT:
  264         case ACPI_PTYPE2_FIXED:
  265         case ACPI_PTYPE2_MIN:
  266         case ACPI_PTYPE2_FIX_VAR:
  267         case ACPI_PTYPE2_VAR_VAR:
  268         default:
  269 
  270             break;
  271         }
  272 
  273         return;
  274     }
  275 
  276     /* Get the first element of the package */
  277 
  278     Op = Op->Asl.Next;
  279 
  280     /* Decode the package type */
  281 
  282     switch (Package->RetInfo.Type)
  283     {
  284     case ACPI_PTYPE_CUSTOM:
  285 
  286         ApCustomPackage (ParentOp, Predefined);
  287         break;
  288 
  289     case ACPI_PTYPE1_FIXED:
  290         /*
  291          * The package count is fixed and there are no subpackages
  292          *
  293          * If package is too small, exit.
  294          * If package is larger than expected, issue warning but continue
  295          */
  296         ExpectedCount = Package->RetInfo.Count1 + Package->RetInfo.Count2;
  297         if (Count < ExpectedCount)
  298         {
  299             goto PackageTooSmall;
  300         }
  301         else if (Count > ExpectedCount)
  302         {
  303             ApPackageTooLarge (Predefined->Info.Name, ParentOp,
  304                 Count, ExpectedCount);
  305         }
  306 
  307         /* Validate all elements of the package */
  308 
  309         ApCheckPackageElements (Predefined->Info.Name, Op,
  310             Package->RetInfo.ObjectType1, Package->RetInfo.Count1,
  311             Package->RetInfo.ObjectType2, Package->RetInfo.Count2);
  312         break;
  313 
  314     case ACPI_PTYPE1_VAR:
  315         /*
  316          * The package count is variable, there are no subpackages,
  317          * and all elements must be of the same type
  318          */
  319         for (i = 0; i < Count; i++)
  320         {
  321             if (!Op)
  322             {
  323                 /*
  324                  * If we get to this point, it means that the package length
  325                  * is larger than the initializer list. Stop processing the
  326                  * package and return because we have run out of package
  327                  * elements to analyze.
  328                  */
  329                 return;
  330             }
  331 
  332             ApCheckObjectType (Predefined->Info.Name, Op,
  333                 Package->RetInfo.ObjectType1, i);
  334             Op = Op->Asl.Next;
  335         }
  336         break;
  337 
  338     case ACPI_PTYPE1_OPTION:
  339         /*
  340          * The package count is variable, there are no subpackages.
  341          * There are a fixed number of required elements, and a variable
  342          * number of optional elements.
  343          *
  344          * Check if package is at least as large as the minimum required
  345          */
  346         ExpectedCount = Package->RetInfo3.Count;
  347         if (Count < ExpectedCount)
  348         {
  349             goto PackageTooSmall;
  350         }
  351 
  352         /* Variable number of sub-objects */
  353 
  354         for (i = 0; i < Count; i++)
  355         {
  356             if (i < Package->RetInfo3.Count)
  357             {
  358                 /* These are the required package elements (0, 1, or 2) */
  359 
  360                 ApCheckObjectType (Predefined->Info.Name, Op,
  361                     Package->RetInfo3.ObjectType[i], i);
  362             }
  363             else
  364             {
  365                 /* These are the optional package elements */
  366 
  367                 ApCheckObjectType (Predefined->Info.Name, Op,
  368                     Package->RetInfo3.TailObjectType, i);
  369             }
  370 
  371             Op = Op->Asl.Next;
  372         }
  373         break;
  374 
  375     case ACPI_PTYPE2_REV_FIXED:
  376 
  377         /* First element is the (Integer) revision */
  378 
  379         ApCheckObjectType (Predefined->Info.Name, Op,
  380             ACPI_RTYPE_INTEGER, 0);
  381 
  382         Op = Op->Asl.Next;
  383         Count--;
  384 
  385         /* Examine the subpackages */
  386 
  387         ApCheckPackageList (Predefined->Info.Name, Op,
  388             Package, 1, Count);
  389         break;
  390 
  391     case ACPI_PTYPE2_PKG_COUNT:
  392 
  393         /* First element is the (Integer) count of subpackages to follow */
  394 
  395         Status = ApCheckObjectType (Predefined->Info.Name, Op,
  396             ACPI_RTYPE_INTEGER, 0);
  397 
  398         /* We must have an integer count from above (otherwise, use Count) */
  399 
  400         if (ACPI_SUCCESS (Status))
  401         {
  402             /*
  403              * Count cannot be larger than the parent package length, but
  404              * allow it to be smaller. The >= accounts for the Integer above.
  405              */
  406             ExpectedCount = (UINT32) Op->Asl.Value.Integer;
  407             if (ExpectedCount >= Count)
  408             {
  409                 goto PackageTooSmall;
  410             }
  411 
  412             Count = ExpectedCount;
  413         }
  414 
  415         Op = Op->Asl.Next;
  416 
  417         /* Examine the subpackages */
  418 
  419         ApCheckPackageList (Predefined->Info.Name, Op,
  420             Package, 1, Count);
  421         break;
  422 
  423     case ACPI_PTYPE2_UUID_PAIR:
  424 
  425         /* The package contains a variable list of UUID Buffer/Package pairs */
  426 
  427         /* The length of the package must be even */
  428 
  429         if (Count & 1)
  430         {
  431             sprintf (AslGbl_MsgBuffer, "%4.4s: Package length, %d, must be even.",
  432                 Predefined->Info.Name, Count);
  433 
  434             AslError (ASL_ERROR, ASL_MSG_RESERVED_PACKAGE_LENGTH,
  435                 ParentOp->Asl.Child, AslGbl_MsgBuffer);
  436         }
  437 
  438         /* Validate the alternating types */
  439 
  440         for (i = 0; i < Count; ++i)
  441         {
  442             if (i & 1)
  443             {
  444                 ApCheckObjectType (Predefined->Info.Name, Op,
  445                     Package->RetInfo.ObjectType2, i);
  446             }
  447             else
  448             {
  449                 ApCheckObjectType (Predefined->Info.Name, Op,
  450                     Package->RetInfo.ObjectType1, i);
  451             }
  452 
  453             Op = Op->Asl.Next;
  454         }
  455 
  456         break;
  457 
  458     case ACPI_PTYPE2_VAR_VAR:
  459 
  460         /* Check for minimum size (ints at beginning + 1 subpackage) */
  461 
  462         ExpectedCount = Package->RetInfo4.Count1 + 1;
  463         if (Count < ExpectedCount)
  464         {
  465             goto PackageTooSmall;
  466         }
  467 
  468         /* Check the non-package elements at beginning of main package */
  469 
  470         for (i = 0; i < Package->RetInfo4.Count1; ++i)
  471         {
  472             ApCheckObjectType (Predefined->Info.Name, Op,
  473                 Package->RetInfo4.ObjectType1, i);
  474             Op = Op->Asl.Next;
  475         }
  476 
  477         /* Examine the variable-length list of subpackages */
  478 
  479         ApCheckPackageList (Predefined->Info.Name, Op,
  480             Package, Package->RetInfo4.Count1, Count);
  481 
  482         break;
  483 
  484     case ACPI_PTYPE2:
  485     case ACPI_PTYPE2_FIXED:
  486     case ACPI_PTYPE2_MIN:
  487     case ACPI_PTYPE2_COUNT:
  488     case ACPI_PTYPE2_FIX_VAR:
  489         /*
  490          * These types all return a single Package that consists of a
  491          * variable number of subpackages.
  492          */
  493 
  494         /* Examine the subpackages */
  495 
  496         ApCheckPackageList (Predefined->Info.Name, Op,
  497             Package, 0, Count);
  498         break;
  499 
  500     default:
  501         return;
  502     }
  503 
  504     return;
  505 
  506 PackageTooSmall:
  507     ApPackageTooSmall (Predefined->Info.Name, ParentOp,
  508         Count, ExpectedCount);
  509 }
  510 
  511 
  512 /*******************************************************************************
  513  *
  514  * FUNCTION:    ApCustomPackage
  515  *
  516  * PARAMETERS:  ParentOp            - Parse op for the package
  517  *              Predefined          - Pointer to package-specific info for
  518  *                                    the method
  519  *
  520  * RETURN:      None
  521  *
  522  * DESCRIPTION: Validate packages that don't fit into the standard model and
  523  *              require custom code.
  524  *
  525  * NOTE: Currently used for the _BIX method only. When needed for two or more
  526  * methods, probably a detect/dispatch mechanism will be required.
  527  *
  528  ******************************************************************************/
  529 
  530 static void
  531 ApCustomPackage (
  532     ACPI_PARSE_OBJECT           *ParentOp,
  533     const ACPI_PREDEFINED_INFO  *Predefined)
  534 {
  535     ACPI_PARSE_OBJECT           *Op;
  536     UINT32                      Count;
  537     UINT32                      ExpectedCount;
  538     UINT32                      Version;
  539 
  540 
  541     /* First child is the package length */
  542 
  543     Op = ParentOp->Asl.Child;
  544     Count = (UINT32) Op->Asl.Value.Integer;
  545 
  546     /* Get the version number, must be Integer */
  547 
  548     Op = Op->Asl.Next;
  549     Version = (UINT32) Op->Asl.Value.Integer;
  550     if (Op->Asl.ParseOpcode != PARSEOP_INTEGER)
  551     {
  552         AslError (ASL_ERROR, ASL_MSG_RESERVED_OPERAND_TYPE, Op, AslGbl_MsgBuffer);
  553         return;
  554     }
  555 
  556     /* Validate count (# of elements) */
  557 
  558     ExpectedCount = 21;         /* Version 1 */
  559     if (Version == 0)
  560     {
  561         ExpectedCount = 20;     /* Version 0 */
  562     }
  563 
  564     if (Count < ExpectedCount)
  565     {
  566         ApPackageTooSmall (Predefined->Info.Name, ParentOp,
  567             Count, ExpectedCount);
  568         return;
  569     }
  570     else if (Count > ExpectedCount)
  571     {
  572         ApPackageTooLarge (Predefined->Info.Name, ParentOp,
  573             Count, ExpectedCount);
  574     }
  575 
  576     /* Validate all elements of the package */
  577 
  578     Op = ApCheckPackageElements (Predefined->Info.Name, Op,
  579         ACPI_RTYPE_INTEGER, 16,
  580         ACPI_RTYPE_STRING, 4);
  581 
  582     /* Version 1 has a single trailing integer */
  583 
  584     if (Version > 0)
  585     {
  586         ApCheckPackageElements (Predefined->Info.Name, Op,
  587             ACPI_RTYPE_INTEGER, 1, 0, 0);
  588     }
  589 }
  590 
  591 
  592 /*******************************************************************************
  593  *
  594  * FUNCTION:    ApCheckPackageElements
  595  *
  596  * PARAMETERS:  PredefinedName      - Name of the predefined object
  597  *              Op                  - Parser op for the package
  598  *              Type1               - Object type for first group
  599  *              Count1              - Count for first group
  600  *              Type2               - Object type for second group
  601  *              Count2              - Count for second group
  602  *
  603  * RETURN:      Next Op peer in the parse tree, after all specified elements
  604  *              have been validated. Used for multiple validations (calls
  605  *              to this function).
  606  *
  607  * DESCRIPTION: Validate all elements of a package. Works with packages that
  608  *              are defined to contain up to two groups of different object
  609  *              types.
  610  *
  611  ******************************************************************************/
  612 
  613 static ACPI_PARSE_OBJECT *
  614 ApCheckPackageElements (
  615     const char              *PredefinedName,
  616     ACPI_PARSE_OBJECT       *Op,
  617     UINT8                   Type1,
  618     UINT32                  Count1,
  619     UINT8                   Type2,
  620     UINT32                  Count2)
  621 {
  622     UINT32                  i;
  623 
  624 
  625     /*
  626      * Up to two groups of package elements are supported by the data
  627      * structure. All elements in each group must be of the same type.
  628      * The second group can have a count of zero.
  629      *
  630      * Aborts check upon a NULL package element, as this means (at compile
  631      * time) that the remainder of the package elements are also NULL
  632      * (This is the only way to create NULL package elements.)
  633      */
  634     for (i = 0; (i < Count1) && Op; i++)
  635     {
  636         ApCheckObjectType (PredefinedName, Op, Type1, i);
  637         Op = Op->Asl.Next;
  638     }
  639 
  640     for (i = 0; (i < Count2) && Op; i++)
  641     {
  642         ApCheckObjectType (PredefinedName, Op, Type2, (i + Count1));
  643         Op = Op->Asl.Next;
  644     }
  645 
  646     return (Op);
  647 }
  648 
  649 
  650 /*******************************************************************************
  651  *
  652  * FUNCTION:    ApCheckPackageList
  653  *
  654  * PARAMETERS:  PredefinedName      - Name of the predefined object
  655  *              ParentOp            - Parser op of the parent package
  656  *              Package             - Package info for this predefined name
  657  *              StartIndex          - Index in parent package where list begins
  658  *              ParentCount         - Element count of parent package
  659  *
  660  * RETURN:      None
  661  *
  662  * DESCRIPTION: Validate the individual package elements for a predefined name.
  663  *              Handles the cases where the predefined name is defined as a
  664  *              Package of Packages (subpackages). These are the types:
  665  *
  666  *              ACPI_PTYPE2
  667  *              ACPI_PTYPE2_FIXED
  668  *              ACPI_PTYPE2_MIN
  669  *              ACPI_PTYPE2_COUNT
  670  *              ACPI_PTYPE2_FIX_VAR
  671  *              ACPI_PTYPE2_VAR_VAR
  672  *
  673  ******************************************************************************/
  674 
  675 static void
  676 ApCheckPackageList (
  677     const char                  *PredefinedName,
  678     ACPI_PARSE_OBJECT           *ParentOp,
  679     const ACPI_PREDEFINED_INFO  *Package,
  680     UINT32                      StartIndex,
  681     UINT32                      ParentCount)
  682 {
  683     ACPI_PARSE_OBJECT           *SubPackageOp = ParentOp;
  684     ACPI_PARSE_OBJECT           *Op;
  685     ACPI_STATUS                 Status;
  686     UINT32                      Count;
  687     UINT32                      ExpectedCount;
  688     UINT32                      i;
  689     UINT32                      j;
  690 
  691 
  692     /*
  693      * Validate each subpackage in the parent Package
  694      *
  695      * Note: We ignore NULL package elements on the assumption that
  696      * they will be initialized by the BIOS or other ASL code.
  697      */
  698     for (i = 0; (i < ParentCount) && SubPackageOp; i++)
  699     {
  700         /* Each object in the list must be of type Package */
  701 
  702         Status = ApCheckObjectType (PredefinedName, SubPackageOp,
  703             ACPI_RTYPE_PACKAGE, i + StartIndex);
  704         if (ACPI_FAILURE (Status))
  705         {
  706             goto NextSubpackage;
  707         }
  708 
  709         /* Examine the different types of expected subpackages */
  710 
  711         Op = SubPackageOp->Asl.Child;
  712 
  713         /* First child is the package length */
  714 
  715         Count = (UINT32) Op->Asl.Value.Integer;
  716         Op = Op->Asl.Next;
  717 
  718         /*
  719          * Most subpackage must have at least one element, with
  720          * only rare exceptions. (_RDI)
  721          */
  722         if (!Count &&
  723             (Package->RetInfo.Type != ACPI_PTYPE2_VAR_VAR))
  724         {
  725             ApZeroLengthPackage (PredefinedName, SubPackageOp);
  726             goto NextSubpackage;
  727         }
  728 
  729         /*
  730          * Decode the package type.
  731          * PTYPE2 indicates that a "package of packages" is expected for
  732          * this name. The various flavors of PTYPE2 indicate the number
  733          * and format of the subpackages.
  734          */
  735         switch (Package->RetInfo.Type)
  736         {
  737         case ACPI_PTYPE2:
  738         case ACPI_PTYPE2_PKG_COUNT:
  739         case ACPI_PTYPE2_REV_FIXED:
  740 
  741             /* Each subpackage has a fixed number of elements */
  742 
  743             ExpectedCount = Package->RetInfo.Count1 + Package->RetInfo.Count2;
  744             if (Count < ExpectedCount)
  745             {
  746                 ApPackageTooSmall (PredefinedName, SubPackageOp,
  747                     Count, ExpectedCount);
  748                 break;
  749             }
  750             if (Count > ExpectedCount)
  751             {
  752                 ApPackageTooLarge (PredefinedName, SubPackageOp,
  753                     Count, ExpectedCount);
  754                 break;
  755             }
  756 
  757             ApCheckPackageElements (PredefinedName, Op,
  758                 Package->RetInfo.ObjectType1, Package->RetInfo.Count1,
  759                 Package->RetInfo.ObjectType2, Package->RetInfo.Count2);
  760             break;
  761 
  762         case ACPI_PTYPE2_FIX_VAR:
  763             /*
  764              * Each subpackage has a fixed number of elements and an
  765              * optional element
  766              */
  767             ExpectedCount = Package->RetInfo.Count1 + Package->RetInfo.Count2;
  768             if (Count < ExpectedCount)
  769             {
  770                 ApPackageTooSmall (PredefinedName, SubPackageOp,
  771                     Count, ExpectedCount);
  772                 break;
  773             }
  774 
  775             ApCheckPackageElements (PredefinedName, Op,
  776                 Package->RetInfo.ObjectType1, Package->RetInfo.Count1,
  777                 Package->RetInfo.ObjectType2,
  778                 Count - Package->RetInfo.Count1);
  779             break;
  780 
  781         case ACPI_PTYPE2_VAR_VAR:
  782             /*
  783              * Must have at least the minimum number elements.
  784              * A zero PkgCount means the number of elements is variable.
  785              */
  786             ExpectedCount = Package->RetInfo4.PkgCount;
  787             if (ExpectedCount && (Count < ExpectedCount))
  788             {
  789                 ApPackageTooSmall (PredefinedName, SubPackageOp,
  790                     Count, 1);
  791                 break;
  792             }
  793 
  794             ApCheckPackageElements (PredefinedName, Op,
  795                 Package->RetInfo4.SubObjectTypes,
  796                 Package->RetInfo4.PkgCount,
  797                 0, 0);
  798             break;
  799 
  800         case ACPI_PTYPE2_FIXED:
  801 
  802             /* Each subpackage has a fixed length */
  803 
  804             ExpectedCount = Package->RetInfo2.Count;
  805             if (Count < ExpectedCount)
  806             {
  807                 ApPackageTooSmall (PredefinedName, SubPackageOp,
  808                     Count, ExpectedCount);
  809                 break;
  810             }
  811             if (Count > ExpectedCount)
  812             {
  813                 ApPackageTooLarge (PredefinedName, SubPackageOp,
  814                     Count, ExpectedCount);
  815                 break;
  816             }
  817 
  818             /* Check each object/type combination */
  819 
  820             for (j = 0; j < ExpectedCount; j++)
  821             {
  822                 ApCheckObjectType (PredefinedName, Op,
  823                     Package->RetInfo2.ObjectType[j], j);
  824 
  825                 Op = Op->Asl.Next;
  826             }
  827             break;
  828 
  829         case ACPI_PTYPE2_MIN:
  830 
  831             /* Each subpackage has a variable but minimum length */
  832 
  833             ExpectedCount = Package->RetInfo.Count1;
  834             if (Count < ExpectedCount)
  835             {
  836                 ApPackageTooSmall (PredefinedName, SubPackageOp,
  837                     Count, ExpectedCount);
  838                 break;
  839             }
  840 
  841             /* Check the type of each subpackage element */
  842 
  843             ApCheckPackageElements (PredefinedName, Op,
  844                 Package->RetInfo.ObjectType1, Count, 0, 0);
  845             break;
  846 
  847         case ACPI_PTYPE2_COUNT:
  848             /*
  849              * First element is the (Integer) count of elements, including
  850              * the count field (the ACPI name is NumElements)
  851              */
  852             Status = ApCheckObjectType (PredefinedName, Op,
  853                 ACPI_RTYPE_INTEGER, 0);
  854 
  855             /* We must have an integer count from above (otherwise, use Count) */
  856 
  857             if (ACPI_SUCCESS (Status))
  858             {
  859                 /*
  860                  * Make sure package is large enough for the Count and is
  861                  * is as large as the minimum size
  862                  */
  863                 ExpectedCount = (UINT32) Op->Asl.Value.Integer;
  864 
  865                 if (Count < ExpectedCount)
  866                 {
  867                     ApPackageTooSmall (PredefinedName, SubPackageOp,
  868                         Count, ExpectedCount);
  869                     break;
  870                 }
  871                 else if (Count > ExpectedCount)
  872                 {
  873                     ApPackageTooLarge (PredefinedName, SubPackageOp,
  874                         Count, ExpectedCount);
  875                 }
  876 
  877                 /* Some names of this type have a minimum length */
  878 
  879                 if (Count < Package->RetInfo.Count1)
  880                 {
  881                     ExpectedCount = Package->RetInfo.Count1;
  882                     ApPackageTooSmall (PredefinedName, SubPackageOp,
  883                         Count, ExpectedCount);
  884                     break;
  885                 }
  886 
  887                 Count = ExpectedCount;
  888             }
  889 
  890             /* Check the type of each subpackage element */
  891 
  892             Op = Op->Asl.Next;
  893             ApCheckPackageElements (PredefinedName, Op,
  894                 Package->RetInfo.ObjectType1, (Count - 1), 0, 0);
  895             break;
  896 
  897         default:
  898             break;
  899         }
  900 
  901 NextSubpackage:
  902         SubPackageOp = SubPackageOp->Asl.Next;
  903     }
  904 }
  905 
  906 
  907 /*******************************************************************************
  908  *
  909  * FUNCTION:    ApPackageTooSmall
  910  *
  911  * PARAMETERS:  PredefinedName      - Name of the predefined object
  912  *              Op                  - Current parser op
  913  *              Count               - Actual package element count
  914  *              ExpectedCount       - Expected package element count
  915  *
  916  * RETURN:      None
  917  *
  918  * DESCRIPTION: Issue error message for a package that is smaller than
  919  *              required.
  920  *
  921  ******************************************************************************/
  922 
  923 static void
  924 ApPackageTooSmall (
  925     const char                  *PredefinedName,
  926     ACPI_PARSE_OBJECT           *Op,
  927     UINT32                      Count,
  928     UINT32                      ExpectedCount)
  929 {
  930 
  931     sprintf (AslGbl_MsgBuffer, "%4.4s: length %u, required minimum is %u",
  932         PredefinedName, Count, ExpectedCount);
  933 
  934     AslError (ASL_ERROR, ASL_MSG_RESERVED_PACKAGE_LENGTH, Op, AslGbl_MsgBuffer);
  935 }
  936 
  937 
  938 /*******************************************************************************
  939  *
  940  * FUNCTION:    ApZeroLengthPackage
  941  *
  942  * PARAMETERS:  PredefinedName      - Name of the predefined object
  943  *              Op                  - Current parser op
  944  *
  945  * RETURN:      None
  946  *
  947  * DESCRIPTION: Issue error message for a zero-length package (a package that
  948  *              is required to have a non-zero length). Variable length
  949  *              packages seem to be allowed to have zero length, however.
  950  *              Even if not allowed, BIOS code does it.
  951  *
  952  ******************************************************************************/
  953 
  954 static void
  955 ApZeroLengthPackage (
  956     const char                  *PredefinedName,
  957     ACPI_PARSE_OBJECT           *Op)
  958 {
  959 
  960     sprintf (AslGbl_MsgBuffer, "%4.4s: length is zero", PredefinedName);
  961 
  962     AslError (ASL_ERROR, ASL_MSG_RESERVED_PACKAGE_LENGTH, Op, AslGbl_MsgBuffer);
  963 }
  964 
  965 
  966 /*******************************************************************************
  967  *
  968  * FUNCTION:    ApPackageTooLarge
  969  *
  970  * PARAMETERS:  PredefinedName      - Name of the predefined object
  971  *              Op                  - Current parser op
  972  *              Count               - Actual package element count
  973  *              ExpectedCount       - Expected package element count
  974  *
  975  * RETURN:      None
  976  *
  977  * DESCRIPTION: Issue a remark for a package that is larger than expected.
  978  *
  979  ******************************************************************************/
  980 
  981 static void
  982 ApPackageTooLarge (
  983     const char                  *PredefinedName,
  984     ACPI_PARSE_OBJECT           *Op,
  985     UINT32                      Count,
  986     UINT32                      ExpectedCount)
  987 {
  988 
  989     sprintf (AslGbl_MsgBuffer, "%4.4s: length is %u, only %u required",
  990         PredefinedName, Count, ExpectedCount);
  991 
  992     AslError (ASL_REMARK, ASL_MSG_RESERVED_PACKAGE_LENGTH, Op, AslGbl_MsgBuffer);
  993 }

Cache object: e349ef0d66c13ae5e8e8dc2d5bdc7d1d


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.