root/drivers/acpi/acpica/nsarguments.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ACPI_MODULE_NAME
  2. acpi_ns_check_acpi_compliance
  3. acpi_ns_check_argument_count

   1 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
   2 /******************************************************************************
   3  *
   4  * Module Name: nsarguments - Validation of args for ACPI predefined methods
   5  *
   6  * Copyright (C) 2000 - 2019, Intel Corp.
   7  *
   8  *****************************************************************************/
   9 
  10 #include <acpi/acpi.h>
  11 #include "accommon.h"
  12 #include "acnamesp.h"
  13 #include "acpredef.h"
  14 
  15 #define _COMPONENT          ACPI_NAMESPACE
  16 ACPI_MODULE_NAME("nsarguments")
  17 
  18 /*******************************************************************************
  19  *
  20  * FUNCTION:    acpi_ns_check_argument_types
  21  *
  22  * PARAMETERS:  info            - Method execution information block
  23  *
  24  * RETURN:      None
  25  *
  26  * DESCRIPTION: Check the incoming argument count and all argument types
  27  *              against the argument type list for a predefined name.
  28  *
  29  ******************************************************************************/
  30 void acpi_ns_check_argument_types(struct acpi_evaluate_info *info)
  31 {
  32         u16 arg_type_list;
  33         u8 arg_count;
  34         u8 arg_type;
  35         u8 user_arg_type;
  36         u32 i;
  37 
  38         /*
  39          * If not a predefined name, cannot typecheck args, because
  40          * we have no idea what argument types are expected.
  41          * Also, ignore typecheck if warnings/errors if this method
  42          * has already been evaluated at least once -- in order
  43          * to suppress repetitive messages.
  44          */
  45         if (!info->predefined || (info->node->flags & ANOBJ_EVALUATED)) {
  46                 return;
  47         }
  48 
  49         arg_type_list = info->predefined->info.argument_list;
  50         arg_count = METHOD_GET_ARG_COUNT(arg_type_list);
  51 
  52         /* Typecheck all arguments */
  53 
  54         for (i = 0; ((i < arg_count) && (i < info->param_count)); i++) {
  55                 arg_type = METHOD_GET_NEXT_TYPE(arg_type_list);
  56                 user_arg_type = info->parameters[i]->common.type;
  57 
  58                 if (user_arg_type != arg_type) {
  59                         ACPI_WARN_PREDEFINED((AE_INFO, info->full_pathname,
  60                                               ACPI_WARN_ALWAYS,
  61                                               "Argument #%u type mismatch - "
  62                                               "Found [%s], ACPI requires [%s]",
  63                                               (i + 1),
  64                                               acpi_ut_get_type_name
  65                                               (user_arg_type),
  66                                               acpi_ut_get_type_name(arg_type)));
  67 
  68                         /* Prevent any additional typechecking for this method */
  69 
  70                         info->node->flags |= ANOBJ_EVALUATED;
  71                 }
  72         }
  73 }
  74 
  75 /*******************************************************************************
  76  *
  77  * FUNCTION:    acpi_ns_check_acpi_compliance
  78  *
  79  * PARAMETERS:  pathname        - Full pathname to the node (for error msgs)
  80  *              node            - Namespace node for the method/object
  81  *              predefined      - Pointer to entry in predefined name table
  82  *
  83  * RETURN:      None
  84  *
  85  * DESCRIPTION: Check that the declared parameter count (in ASL/AML) for a
  86  *              predefined name is what is expected (matches what is defined in
  87  *              the ACPI specification for this predefined name.)
  88  *
  89  ******************************************************************************/
  90 
  91 void
  92 acpi_ns_check_acpi_compliance(char *pathname,
  93                               struct acpi_namespace_node *node,
  94                               const union acpi_predefined_info *predefined)
  95 {
  96         u32 aml_param_count;
  97         u32 required_param_count;
  98 
  99         if (!predefined || (node->flags & ANOBJ_EVALUATED)) {
 100                 return;
 101         }
 102 
 103         /* Get the ACPI-required arg count from the predefined info table */
 104 
 105         required_param_count =
 106             METHOD_GET_ARG_COUNT(predefined->info.argument_list);
 107 
 108         /*
 109          * If this object is not a control method, we can check if the ACPI
 110          * spec requires that it be a method.
 111          */
 112         if (node->type != ACPI_TYPE_METHOD) {
 113                 if (required_param_count > 0) {
 114 
 115                         /* Object requires args, must be implemented as a method */
 116 
 117                         ACPI_BIOS_ERROR_PREDEFINED((AE_INFO, pathname,
 118                                                     ACPI_WARN_ALWAYS,
 119                                                     "Object (%s) must be a control method with %u arguments",
 120                                                     acpi_ut_get_type_name(node->
 121                                                                           type),
 122                                                     required_param_count));
 123                 } else if (!required_param_count
 124                            && !predefined->info.expected_btypes) {
 125 
 126                         /* Object requires no args and no return value, must be a method */
 127 
 128                         ACPI_BIOS_ERROR_PREDEFINED((AE_INFO, pathname,
 129                                                     ACPI_WARN_ALWAYS,
 130                                                     "Object (%s) must be a control method "
 131                                                     "with no arguments and no return value",
 132                                                     acpi_ut_get_type_name(node->
 133                                                                           type)));
 134                 }
 135 
 136                 return;
 137         }
 138 
 139         /*
 140          * This is a control method.
 141          * Check that the ASL/AML-defined parameter count for this method
 142          * matches the ACPI-required parameter count
 143          *
 144          * Some methods are allowed to have a "minimum" number of args (_SCP)
 145          * because their definition in ACPI has changed over time.
 146          *
 147          * Note: These are BIOS errors in the declaration of the object
 148          */
 149         aml_param_count = node->object->method.param_count;
 150 
 151         if (aml_param_count < required_param_count) {
 152                 ACPI_BIOS_ERROR_PREDEFINED((AE_INFO, pathname, ACPI_WARN_ALWAYS,
 153                                             "Insufficient arguments - "
 154                                             "ASL declared %u, ACPI requires %u",
 155                                             aml_param_count,
 156                                             required_param_count));
 157         } else if ((aml_param_count > required_param_count)
 158                    && !(predefined->info.
 159                         argument_list & ARG_COUNT_IS_MINIMUM)) {
 160                 ACPI_BIOS_ERROR_PREDEFINED((AE_INFO, pathname, ACPI_WARN_ALWAYS,
 161                                             "Excess arguments - "
 162                                             "ASL declared %u, ACPI requires %u",
 163                                             aml_param_count,
 164                                             required_param_count));
 165         }
 166 }
 167 
 168 /*******************************************************************************
 169  *
 170  * FUNCTION:    acpi_ns_check_argument_count
 171  *
 172  * PARAMETERS:  pathname        - Full pathname to the node (for error msgs)
 173  *              node            - Namespace node for the method/object
 174  *              user_param_count - Number of args passed in by the caller
 175  *              predefined      - Pointer to entry in predefined name table
 176  *
 177  * RETURN:      None
 178  *
 179  * DESCRIPTION: Check that incoming argument count matches the declared
 180  *              parameter count (in the ASL/AML) for an object.
 181  *
 182  ******************************************************************************/
 183 
 184 void
 185 acpi_ns_check_argument_count(char *pathname,
 186                              struct acpi_namespace_node *node,
 187                              u32 user_param_count,
 188                              const union acpi_predefined_info *predefined)
 189 {
 190         u32 aml_param_count;
 191         u32 required_param_count;
 192 
 193         if (node->flags & ANOBJ_EVALUATED) {
 194                 return;
 195         }
 196 
 197         if (!predefined) {
 198                 /*
 199                  * Not a predefined name. Check the incoming user argument count
 200                  * against the count that is specified in the method/object.
 201                  */
 202                 if (node->type != ACPI_TYPE_METHOD) {
 203                         if (user_param_count) {
 204                                 ACPI_INFO_PREDEFINED((AE_INFO, pathname,
 205                                                       ACPI_WARN_ALWAYS,
 206                                                       "%u arguments were passed to a non-method ACPI object (%s)",
 207                                                       user_param_count,
 208                                                       acpi_ut_get_type_name
 209                                                       (node->type)));
 210                         }
 211 
 212                         return;
 213                 }
 214 
 215                 /*
 216                  * This is a control method. Check the parameter count.
 217                  * We can only check the incoming argument count against the
 218                  * argument count declared for the method in the ASL/AML.
 219                  *
 220                  * Emit a message if too few or too many arguments have been passed
 221                  * by the caller.
 222                  *
 223                  * Note: Too many arguments will not cause the method to
 224                  * fail. However, the method will fail if there are too few
 225                  * arguments and the method attempts to use one of the missing ones.
 226                  */
 227                 aml_param_count = node->object->method.param_count;
 228 
 229                 if (user_param_count < aml_param_count) {
 230                         ACPI_WARN_PREDEFINED((AE_INFO, pathname,
 231                                               ACPI_WARN_ALWAYS,
 232                                               "Insufficient arguments - "
 233                                               "Caller passed %u, method requires %u",
 234                                               user_param_count,
 235                                               aml_param_count));
 236                 } else if (user_param_count > aml_param_count) {
 237                         ACPI_INFO_PREDEFINED((AE_INFO, pathname,
 238                                               ACPI_WARN_ALWAYS,
 239                                               "Excess arguments - "
 240                                               "Caller passed %u, method requires %u",
 241                                               user_param_count,
 242                                               aml_param_count));
 243                 }
 244 
 245                 return;
 246         }
 247 
 248         /*
 249          * This is a predefined name. Validate the user-supplied parameter
 250          * count against the ACPI specification. We don't validate against
 251          * the method itself because what is important here is that the
 252          * caller is in conformance with the spec. (The arg count for the
 253          * method was checked against the ACPI spec earlier.)
 254          *
 255          * Some methods are allowed to have a "minimum" number of args (_SCP)
 256          * because their definition in ACPI has changed over time.
 257          */
 258         required_param_count =
 259             METHOD_GET_ARG_COUNT(predefined->info.argument_list);
 260 
 261         if (user_param_count < required_param_count) {
 262                 ACPI_WARN_PREDEFINED((AE_INFO, pathname, ACPI_WARN_ALWAYS,
 263                                       "Insufficient arguments - "
 264                                       "Caller passed %u, ACPI requires %u",
 265                                       user_param_count, required_param_count));
 266         } else if ((user_param_count > required_param_count) &&
 267                    !(predefined->info.argument_list & ARG_COUNT_IS_MINIMUM)) {
 268                 ACPI_INFO_PREDEFINED((AE_INFO, pathname, ACPI_WARN_ALWAYS,
 269                                       "Excess arguments - "
 270                                       "Caller passed %u, ACPI requires %u",
 271                                       user_param_count, required_param_count));
 272         }
 273 }

/* [<][>][^][v][top][bottom][index][help] */