Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

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