Home | History | Annotate | Line # | Download | only in namespace
nsarguments.c revision 1.1.1.10.2.1
      1           1.1  christos /******************************************************************************
      2           1.1  christos  *
      3           1.1  christos  * Module Name: nsarguments - Validation of args for ACPI predefined methods
      4           1.1  christos  *
      5           1.1  christos  *****************************************************************************/
      6           1.1  christos 
      7           1.1  christos /*
      8  1.1.1.10.2.1   thorpej  * Copyright (C) 2000 - 2021, Intel Corp.
      9           1.1  christos  * All rights reserved.
     10           1.1  christos  *
     11           1.1  christos  * Redistribution and use in source and binary forms, with or without
     12           1.1  christos  * modification, are permitted provided that the following conditions
     13           1.1  christos  * are met:
     14           1.1  christos  * 1. Redistributions of source code must retain the above copyright
     15           1.1  christos  *    notice, this list of conditions, and the following disclaimer,
     16           1.1  christos  *    without modification.
     17           1.1  christos  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
     18           1.1  christos  *    substantially similar to the "NO WARRANTY" disclaimer below
     19           1.1  christos  *    ("Disclaimer") and any redistribution must be conditioned upon
     20           1.1  christos  *    including a substantially similar Disclaimer requirement for further
     21           1.1  christos  *    binary redistribution.
     22           1.1  christos  * 3. Neither the names of the above-listed copyright holders nor the names
     23           1.1  christos  *    of any contributors may be used to endorse or promote products derived
     24           1.1  christos  *    from this software without specific prior written permission.
     25           1.1  christos  *
     26           1.1  christos  * Alternatively, this software may be distributed under the terms of the
     27           1.1  christos  * GNU General Public License ("GPL") version 2 as published by the Free
     28           1.1  christos  * Software Foundation.
     29           1.1  christos  *
     30           1.1  christos  * NO WARRANTY
     31           1.1  christos  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     32           1.1  christos  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     33  1.1.1.10.2.1   thorpej  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     34           1.1  christos  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     35           1.1  christos  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     36           1.1  christos  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     37           1.1  christos  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     38           1.1  christos  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
     39           1.1  christos  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
     40           1.1  christos  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     41           1.1  christos  * POSSIBILITY OF SUCH DAMAGES.
     42           1.1  christos  */
     43           1.1  christos 
     44           1.1  christos #include "acpi.h"
     45           1.1  christos #include "accommon.h"
     46           1.1  christos #include "acnamesp.h"
     47           1.1  christos #include "acpredef.h"
     48           1.1  christos 
     49           1.1  christos 
     50           1.1  christos #define _COMPONENT          ACPI_NAMESPACE
     51           1.1  christos         ACPI_MODULE_NAME    ("nsarguments")
     52           1.1  christos 
     53           1.1  christos 
     54           1.1  christos /*******************************************************************************
     55           1.1  christos  *
     56           1.1  christos  * FUNCTION:    AcpiNsCheckArgumentTypes
     57           1.1  christos  *
     58           1.1  christos  * PARAMETERS:  Info            - Method execution information block
     59           1.1  christos  *
     60           1.1  christos  * RETURN:      None
     61           1.1  christos  *
     62           1.1  christos  * DESCRIPTION: Check the incoming argument count and all argument types
     63           1.1  christos  *              against the argument type list for a predefined name.
     64           1.1  christos  *
     65           1.1  christos  ******************************************************************************/
     66           1.1  christos 
     67           1.1  christos void
     68           1.1  christos AcpiNsCheckArgumentTypes (
     69           1.1  christos     ACPI_EVALUATE_INFO          *Info)
     70           1.1  christos {
     71           1.1  christos     UINT16                      ArgTypeList;
     72           1.1  christos     UINT8                       ArgCount;
     73           1.1  christos     UINT8                       ArgType;
     74           1.1  christos     UINT8                       UserArgType;
     75           1.1  christos     UINT32                      i;
     76           1.1  christos 
     77           1.1  christos 
     78       1.1.1.6  christos     /*
     79       1.1.1.6  christos      * If not a predefined name, cannot typecheck args, because
     80       1.1.1.6  christos      * we have no idea what argument types are expected.
     81       1.1.1.6  christos      * Also, ignore typecheck if warnings/errors if this method
     82       1.1.1.6  christos      * has already been evaluated at least once -- in order
     83       1.1.1.6  christos      * to suppress repetitive messages.
     84       1.1.1.6  christos      */
     85       1.1.1.6  christos     if (!Info->Predefined || (Info->Node->Flags & ANOBJ_EVALUATED))
     86           1.1  christos     {
     87           1.1  christos         return;
     88           1.1  christos     }
     89           1.1  christos 
     90           1.1  christos     ArgTypeList = Info->Predefined->Info.ArgumentList;
     91           1.1  christos     ArgCount = METHOD_GET_ARG_COUNT (ArgTypeList);
     92           1.1  christos 
     93           1.1  christos     /* Typecheck all arguments */
     94           1.1  christos 
     95           1.1  christos     for (i = 0; ((i < ArgCount) && (i < Info->ParamCount)); i++)
     96           1.1  christos     {
     97           1.1  christos         ArgType = METHOD_GET_NEXT_TYPE (ArgTypeList);
     98           1.1  christos         UserArgType = Info->Parameters[i]->Common.Type;
     99           1.1  christos 
    100      1.1.1.10  christos         /* No typechecking for ACPI_TYPE_ANY */
    101      1.1.1.10  christos 
    102      1.1.1.10  christos         if ((UserArgType != ArgType) && (ArgType != ACPI_TYPE_ANY))
    103           1.1  christos         {
    104           1.1  christos             ACPI_WARN_PREDEFINED ((AE_INFO, Info->FullPathname, ACPI_WARN_ALWAYS,
    105           1.1  christos                 "Argument #%u type mismatch - "
    106           1.1  christos                 "Found [%s], ACPI requires [%s]", (i + 1),
    107           1.1  christos                 AcpiUtGetTypeName (UserArgType),
    108           1.1  christos                 AcpiUtGetTypeName (ArgType)));
    109       1.1.1.6  christos 
    110       1.1.1.6  christos             /* Prevent any additional typechecking for this method */
    111       1.1.1.6  christos 
    112       1.1.1.6  christos             Info->Node->Flags |= ANOBJ_EVALUATED;
    113           1.1  christos         }
    114           1.1  christos     }
    115           1.1  christos }
    116           1.1  christos 
    117           1.1  christos 
    118           1.1  christos /*******************************************************************************
    119           1.1  christos  *
    120           1.1  christos  * FUNCTION:    AcpiNsCheckAcpiCompliance
    121           1.1  christos  *
    122           1.1  christos  * PARAMETERS:  Pathname        - Full pathname to the node (for error msgs)
    123           1.1  christos  *              Node            - Namespace node for the method/object
    124           1.1  christos  *              Predefined      - Pointer to entry in predefined name table
    125           1.1  christos  *
    126           1.1  christos  * RETURN:      None
    127           1.1  christos  *
    128           1.1  christos  * DESCRIPTION: Check that the declared parameter count (in ASL/AML) for a
    129           1.1  christos  *              predefined name is what is expected (matches what is defined in
    130           1.1  christos  *              the ACPI specification for this predefined name.)
    131           1.1  christos  *
    132           1.1  christos  ******************************************************************************/
    133           1.1  christos 
    134           1.1  christos void
    135           1.1  christos AcpiNsCheckAcpiCompliance (
    136           1.1  christos     char                        *Pathname,
    137           1.1  christos     ACPI_NAMESPACE_NODE         *Node,
    138           1.1  christos     const ACPI_PREDEFINED_INFO  *Predefined)
    139           1.1  christos {
    140           1.1  christos     UINT32                      AmlParamCount;
    141           1.1  christos     UINT32                      RequiredParamCount;
    142           1.1  christos 
    143           1.1  christos 
    144       1.1.1.6  christos     if (!Predefined || (Node->Flags & ANOBJ_EVALUATED))
    145           1.1  christos     {
    146           1.1  christos         return;
    147           1.1  christos     }
    148           1.1  christos 
    149           1.1  christos     /* Get the ACPI-required arg count from the predefined info table */
    150           1.1  christos 
    151       1.1.1.4  christos     RequiredParamCount =
    152       1.1.1.4  christos         METHOD_GET_ARG_COUNT (Predefined->Info.ArgumentList);
    153           1.1  christos 
    154           1.1  christos     /*
    155           1.1  christos      * If this object is not a control method, we can check if the ACPI
    156           1.1  christos      * spec requires that it be a method.
    157           1.1  christos      */
    158           1.1  christos     if (Node->Type != ACPI_TYPE_METHOD)
    159           1.1  christos     {
    160           1.1  christos         if (RequiredParamCount > 0)
    161           1.1  christos         {
    162           1.1  christos             /* Object requires args, must be implemented as a method */
    163           1.1  christos 
    164           1.1  christos             ACPI_BIOS_ERROR_PREDEFINED ((AE_INFO, Pathname, ACPI_WARN_ALWAYS,
    165           1.1  christos                 "Object (%s) must be a control method with %u arguments",
    166           1.1  christos                 AcpiUtGetTypeName (Node->Type), RequiredParamCount));
    167           1.1  christos         }
    168           1.1  christos         else if (!RequiredParamCount && !Predefined->Info.ExpectedBtypes)
    169           1.1  christos         {
    170           1.1  christos             /* Object requires no args and no return value, must be a method */
    171           1.1  christos 
    172           1.1  christos             ACPI_BIOS_ERROR_PREDEFINED ((AE_INFO, Pathname, ACPI_WARN_ALWAYS,
    173           1.1  christos                 "Object (%s) must be a control method "
    174           1.1  christos                 "with no arguments and no return value",
    175           1.1  christos                 AcpiUtGetTypeName (Node->Type)));
    176           1.1  christos         }
    177           1.1  christos 
    178           1.1  christos         return;
    179           1.1  christos     }
    180           1.1  christos 
    181           1.1  christos     /*
    182           1.1  christos      * This is a control method.
    183           1.1  christos      * Check that the ASL/AML-defined parameter count for this method
    184           1.1  christos      * matches the ACPI-required parameter count
    185           1.1  christos      *
    186           1.1  christos      * Some methods are allowed to have a "minimum" number of args (_SCP)
    187           1.1  christos      * because their definition in ACPI has changed over time.
    188           1.1  christos      *
    189           1.1  christos      * Note: These are BIOS errors in the declaration of the object
    190           1.1  christos      */
    191           1.1  christos     AmlParamCount = Node->Object->Method.ParamCount;
    192           1.1  christos 
    193           1.1  christos     if (AmlParamCount < RequiredParamCount)
    194           1.1  christos     {
    195           1.1  christos         ACPI_BIOS_ERROR_PREDEFINED ((AE_INFO, Pathname, ACPI_WARN_ALWAYS,
    196           1.1  christos             "Insufficient arguments - "
    197           1.1  christos             "ASL declared %u, ACPI requires %u",
    198           1.1  christos             AmlParamCount, RequiredParamCount));
    199           1.1  christos     }
    200           1.1  christos     else if ((AmlParamCount > RequiredParamCount) &&
    201           1.1  christos         !(Predefined->Info.ArgumentList & ARG_COUNT_IS_MINIMUM))
    202           1.1  christos     {
    203           1.1  christos         ACPI_BIOS_ERROR_PREDEFINED ((AE_INFO, Pathname, ACPI_WARN_ALWAYS,
    204           1.1  christos             "Excess arguments - "
    205           1.1  christos             "ASL declared %u, ACPI requires %u",
    206           1.1  christos             AmlParamCount, RequiredParamCount));
    207           1.1  christos     }
    208           1.1  christos }
    209           1.1  christos 
    210           1.1  christos 
    211           1.1  christos /*******************************************************************************
    212           1.1  christos  *
    213           1.1  christos  * FUNCTION:    AcpiNsCheckArgumentCount
    214           1.1  christos  *
    215           1.1  christos  * PARAMETERS:  Pathname        - Full pathname to the node (for error msgs)
    216           1.1  christos  *              Node            - Namespace node for the method/object
    217           1.1  christos  *              UserParamCount  - Number of args passed in by the caller
    218           1.1  christos  *              Predefined      - Pointer to entry in predefined name table
    219           1.1  christos  *
    220           1.1  christos  * RETURN:      None
    221           1.1  christos  *
    222           1.1  christos  * DESCRIPTION: Check that incoming argument count matches the declared
    223           1.1  christos  *              parameter count (in the ASL/AML) for an object.
    224           1.1  christos  *
    225           1.1  christos  ******************************************************************************/
    226           1.1  christos 
    227           1.1  christos void
    228           1.1  christos AcpiNsCheckArgumentCount (
    229           1.1  christos     char                        *Pathname,
    230           1.1  christos     ACPI_NAMESPACE_NODE         *Node,
    231           1.1  christos     UINT32                      UserParamCount,
    232           1.1  christos     const ACPI_PREDEFINED_INFO  *Predefined)
    233           1.1  christos {
    234           1.1  christos     UINT32                      AmlParamCount;
    235           1.1  christos     UINT32                      RequiredParamCount;
    236           1.1  christos 
    237           1.1  christos 
    238       1.1.1.6  christos     if (Node->Flags & ANOBJ_EVALUATED)
    239       1.1.1.6  christos     {
    240       1.1.1.6  christos         return;
    241       1.1.1.6  christos     }
    242       1.1.1.6  christos 
    243           1.1  christos     if (!Predefined)
    244           1.1  christos     {
    245           1.1  christos         /*
    246           1.1  christos          * Not a predefined name. Check the incoming user argument count
    247           1.1  christos          * against the count that is specified in the method/object.
    248           1.1  christos          */
    249           1.1  christos         if (Node->Type != ACPI_TYPE_METHOD)
    250           1.1  christos         {
    251           1.1  christos             if (UserParamCount)
    252           1.1  christos             {
    253           1.1  christos                 ACPI_INFO_PREDEFINED ((AE_INFO, Pathname, ACPI_WARN_ALWAYS,
    254           1.1  christos                     "%u arguments were passed to a non-method ACPI object (%s)",
    255           1.1  christos                     UserParamCount, AcpiUtGetTypeName (Node->Type)));
    256           1.1  christos             }
    257           1.1  christos 
    258           1.1  christos             return;
    259           1.1  christos         }
    260           1.1  christos 
    261           1.1  christos         /*
    262           1.1  christos          * This is a control method. Check the parameter count.
    263           1.1  christos          * We can only check the incoming argument count against the
    264           1.1  christos          * argument count declared for the method in the ASL/AML.
    265           1.1  christos          *
    266           1.1  christos          * Emit a message if too few or too many arguments have been passed
    267           1.1  christos          * by the caller.
    268           1.1  christos          *
    269           1.1  christos          * Note: Too many arguments will not cause the method to
    270           1.1  christos          * fail. However, the method will fail if there are too few
    271           1.1  christos          * arguments and the method attempts to use one of the missing ones.
    272           1.1  christos          */
    273           1.1  christos         AmlParamCount = Node->Object->Method.ParamCount;
    274           1.1  christos 
    275           1.1  christos         if (UserParamCount < AmlParamCount)
    276           1.1  christos         {
    277           1.1  christos             ACPI_WARN_PREDEFINED ((AE_INFO, Pathname, ACPI_WARN_ALWAYS,
    278           1.1  christos                 "Insufficient arguments - "
    279           1.1  christos                 "Caller passed %u, method requires %u",
    280           1.1  christos                 UserParamCount, AmlParamCount));
    281           1.1  christos         }
    282           1.1  christos         else if (UserParamCount > AmlParamCount)
    283           1.1  christos         {
    284           1.1  christos             ACPI_INFO_PREDEFINED ((AE_INFO, Pathname, ACPI_WARN_ALWAYS,
    285           1.1  christos                 "Excess arguments - "
    286           1.1  christos                 "Caller passed %u, method requires %u",
    287           1.1  christos                 UserParamCount, AmlParamCount));
    288           1.1  christos         }
    289           1.1  christos 
    290           1.1  christos         return;
    291           1.1  christos     }
    292           1.1  christos 
    293           1.1  christos     /*
    294           1.1  christos      * This is a predefined name. Validate the user-supplied parameter
    295           1.1  christos      * count against the ACPI specification. We don't validate against
    296           1.1  christos      * the method itself because what is important here is that the
    297           1.1  christos      * caller is in conformance with the spec. (The arg count for the
    298           1.1  christos      * method was checked against the ACPI spec earlier.)
    299           1.1  christos      *
    300           1.1  christos      * Some methods are allowed to have a "minimum" number of args (_SCP)
    301           1.1  christos      * because their definition in ACPI has changed over time.
    302           1.1  christos      */
    303       1.1.1.4  christos     RequiredParamCount =
    304       1.1.1.4  christos         METHOD_GET_ARG_COUNT (Predefined->Info.ArgumentList);
    305           1.1  christos 
    306           1.1  christos     if (UserParamCount < RequiredParamCount)
    307           1.1  christos     {
    308           1.1  christos         ACPI_WARN_PREDEFINED ((AE_INFO, Pathname, ACPI_WARN_ALWAYS,
    309           1.1  christos             "Insufficient arguments - "
    310           1.1  christos             "Caller passed %u, ACPI requires %u",
    311           1.1  christos             UserParamCount, RequiredParamCount));
    312           1.1  christos     }
    313           1.1  christos     else if ((UserParamCount > RequiredParamCount) &&
    314           1.1  christos         !(Predefined->Info.ArgumentList & ARG_COUNT_IS_MINIMUM))
    315           1.1  christos     {
    316           1.1  christos         ACPI_INFO_PREDEFINED ((AE_INFO, Pathname, ACPI_WARN_ALWAYS,
    317           1.1  christos             "Excess arguments - "
    318           1.1  christos             "Caller passed %u, ACPI requires %u",
    319           1.1  christos             UserParamCount, RequiredParamCount));
    320           1.1  christos     }
    321           1.1  christos }
    322