Subversion Repositories Kolibri OS

Rev

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

  1. /******************************************************************************
  2.  *
  3.  * Module Name: nspredef - Validation of ACPI predefined methods and objects
  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. #define ACPI_CREATE_PREDEFINED_TABLE
  45.  
  46. #include <acpi/acpi.h>
  47. #include "accommon.h"
  48. #include "acnamesp.h"
  49. #include "acpredef.h"
  50.  
  51. #define _COMPONENT          ACPI_NAMESPACE
  52. ACPI_MODULE_NAME("nspredef")
  53.  
  54. /*******************************************************************************
  55.  *
  56.  * This module validates predefined ACPI objects that appear in the namespace,
  57.  * at the time they are evaluated (via acpi_evaluate_object). The purpose of this
  58.  * validation is to detect problems with BIOS-exposed predefined ACPI objects
  59.  * before the results are returned to the ACPI-related drivers.
  60.  *
  61.  * There are several areas that are validated:
  62.  *
  63.  *  1) The number of input arguments as defined by the method/object in the
  64.  *     ASL is validated against the ACPI specification.
  65.  *  2) The type of the return object (if any) is validated against the ACPI
  66.  *     specification.
  67.  *  3) For returned package objects, the count of package elements is
  68.  *     validated, as well as the type of each package element. Nested
  69.  *     packages are supported.
  70.  *
  71.  * For any problems found, a warning message is issued.
  72.  *
  73.  ******************************************************************************/
  74. /* Local prototypes */
  75. static acpi_status
  76. acpi_ns_check_reference(struct acpi_evaluate_info *info,
  77.                         union acpi_operand_object *return_object);
  78.  
  79. static u32 acpi_ns_get_bitmapped_type(union acpi_operand_object *return_object);
  80.  
  81. /*******************************************************************************
  82.  *
  83.  * FUNCTION:    acpi_ns_check_return_value
  84.  *
  85.  * PARAMETERS:  node            - Namespace node for the method/object
  86.  *              info            - Method execution information block
  87.  *              user_param_count - Number of parameters actually passed
  88.  *              return_status   - Status from the object evaluation
  89.  *              return_object_ptr - Pointer to the object returned from the
  90.  *                                evaluation of a method or object
  91.  *
  92.  * RETURN:      Status
  93.  *
  94.  * DESCRIPTION: Check the value returned from a predefined name.
  95.  *
  96.  ******************************************************************************/
  97.  
  98. acpi_status
  99. acpi_ns_check_return_value(struct acpi_namespace_node *node,
  100.                            struct acpi_evaluate_info *info,
  101.                            u32 user_param_count,
  102.                            acpi_status return_status,
  103.                            union acpi_operand_object **return_object_ptr)
  104. {
  105.         acpi_status status;
  106.         const union acpi_predefined_info *predefined;
  107.  
  108.         /* If not a predefined name, we cannot validate the return object */
  109.  
  110.         predefined = info->predefined;
  111.         if (!predefined) {
  112.                 return (AE_OK);
  113.         }
  114.  
  115.         /*
  116.          * If the method failed or did not actually return an object, we cannot
  117.          * validate the return object
  118.          */
  119.         if ((return_status != AE_OK) && (return_status != AE_CTRL_RETURN_VALUE)) {
  120.                 return (AE_OK);
  121.         }
  122.  
  123.         /*
  124.          * Return value validation and possible repair.
  125.          *
  126.          * 1) Don't perform return value validation/repair if this feature
  127.          * has been disabled via a global option.
  128.          *
  129.          * 2) We have a return value, but if one wasn't expected, just exit,
  130.          * this is not a problem. For example, if the "Implicit Return"
  131.          * feature is enabled, methods will always return a value.
  132.          *
  133.          * 3) If the return value can be of any type, then we cannot perform
  134.          * any validation, just exit.
  135.          */
  136.         if (acpi_gbl_disable_auto_repair ||
  137.             (!predefined->info.expected_btypes) ||
  138.             (predefined->info.expected_btypes == ACPI_RTYPE_ALL)) {
  139.                 return (AE_OK);
  140.         }
  141.  
  142.         /*
  143.          * Check that the type of the main return object is what is expected
  144.          * for this predefined name
  145.          */
  146.         status = acpi_ns_check_object_type(info, return_object_ptr,
  147.                                            predefined->info.expected_btypes,
  148.                                            ACPI_NOT_PACKAGE_ELEMENT);
  149.         if (ACPI_FAILURE(status)) {
  150.                 goto exit;
  151.         }
  152.  
  153.         /*
  154.          *
  155.          * 4) If there is no return value and it is optional, just return
  156.          * AE_OK (_WAK).
  157.          */
  158.         if (!(*return_object_ptr)) {
  159.                 goto exit;
  160.         }
  161.  
  162.         /*
  163.          * For returned Package objects, check the type of all sub-objects.
  164.          * Note: Package may have been newly created by call above.
  165.          */
  166.         if ((*return_object_ptr)->common.type == ACPI_TYPE_PACKAGE) {
  167.                 info->parent_package = *return_object_ptr;
  168.                 status = acpi_ns_check_package(info, return_object_ptr);
  169.                 if (ACPI_FAILURE(status)) {
  170.  
  171.                         /* We might be able to fix some errors */
  172.  
  173.                         if ((status != AE_AML_OPERAND_TYPE) &&
  174.                             (status != AE_AML_OPERAND_VALUE)) {
  175.                                 goto exit;
  176.                         }
  177.                 }
  178.         }
  179.  
  180.         /*
  181.          * The return object was OK, or it was successfully repaired above.
  182.          * Now make some additional checks such as verifying that package
  183.          * objects are sorted correctly (if required) or buffer objects have
  184.          * the correct data width (bytes vs. dwords). These repairs are
  185.          * performed on a per-name basis, i.e., the code is specific to
  186.          * particular predefined names.
  187.          */
  188.         status = acpi_ns_complex_repairs(info, node, status, return_object_ptr);
  189.  
  190. exit:
  191.         /*
  192.          * If the object validation failed or if we successfully repaired one
  193.          * or more objects, mark the parent node to suppress further warning
  194.          * messages during the next evaluation of the same method/object.
  195.          */
  196.         if (ACPI_FAILURE(status) || (info->return_flags & ACPI_OBJECT_REPAIRED)) {
  197.                 node->flags |= ANOBJ_EVALUATED;
  198.         }
  199.  
  200.         return (status);
  201. }
  202.  
  203. /*******************************************************************************
  204.  *
  205.  * FUNCTION:    acpi_ns_check_object_type
  206.  *
  207.  * PARAMETERS:  info            - Method execution information block
  208.  *              return_object_ptr - Pointer to the object returned from the
  209.  *                                evaluation of a method or object
  210.  *              expected_btypes - Bitmap of expected return type(s)
  211.  *              package_index   - Index of object within parent package (if
  212.  *                                applicable - ACPI_NOT_PACKAGE_ELEMENT
  213.  *                                otherwise)
  214.  *
  215.  * RETURN:      Status
  216.  *
  217.  * DESCRIPTION: Check the type of the return object against the expected object
  218.  *              type(s). Use of Btype allows multiple expected object types.
  219.  *
  220.  ******************************************************************************/
  221.  
  222. acpi_status
  223. acpi_ns_check_object_type(struct acpi_evaluate_info *info,
  224.                           union acpi_operand_object **return_object_ptr,
  225.                           u32 expected_btypes, u32 package_index)
  226. {
  227.         union acpi_operand_object *return_object = *return_object_ptr;
  228.         acpi_status status = AE_OK;
  229.         char type_buffer[96];   /* Room for 10 types */
  230.  
  231.         /* A Namespace node should not get here, but make sure */
  232.  
  233.         if (return_object &&
  234.             ACPI_GET_DESCRIPTOR_TYPE(return_object) == ACPI_DESC_TYPE_NAMED) {
  235.                 ACPI_WARN_PREDEFINED((AE_INFO, info->full_pathname,
  236.                                       info->node_flags,
  237.                                       "Invalid return type - Found a Namespace node [%4.4s] type %s",
  238.                                       return_object->node.name.ascii,
  239.                                       acpi_ut_get_type_name(return_object->node.
  240.                                                             type)));
  241.                 return (AE_AML_OPERAND_TYPE);
  242.         }
  243.  
  244.         /*
  245.          * Convert the object type (ACPI_TYPE_xxx) to a bitmapped object type.
  246.          * The bitmapped type allows multiple possible return types.
  247.          *
  248.          * Note, the cases below must handle all of the possible types returned
  249.          * from all of the predefined names (including elements of returned
  250.          * packages)
  251.          */
  252.         info->return_btype = acpi_ns_get_bitmapped_type(return_object);
  253.         if (info->return_btype == ACPI_RTYPE_ANY) {
  254.  
  255.                 /* Not one of the supported objects, must be incorrect */
  256.                 goto type_error_exit;
  257.         }
  258.  
  259.         /* For reference objects, check that the reference type is correct */
  260.  
  261.         if ((info->return_btype & expected_btypes) == ACPI_RTYPE_REFERENCE) {
  262.                 status = acpi_ns_check_reference(info, return_object);
  263.                 return (status);
  264.         }
  265.  
  266.         /* Attempt simple repair of the returned object if necessary */
  267.  
  268.         status = acpi_ns_simple_repair(info, expected_btypes,
  269.                                        package_index, return_object_ptr);
  270.         if (ACPI_SUCCESS(status)) {
  271.                 return (AE_OK); /* Successful repair */
  272.         }
  273.  
  274. type_error_exit:
  275.  
  276.         /* Create a string with all expected types for this predefined object */
  277.  
  278.         acpi_ut_get_expected_return_types(type_buffer, expected_btypes);
  279.  
  280.         if (!return_object) {
  281.                 ACPI_WARN_PREDEFINED((AE_INFO, info->full_pathname,
  282.                                       info->node_flags,
  283.                                       "Expected return object of type %s",
  284.                                       type_buffer));
  285.         } else if (package_index == ACPI_NOT_PACKAGE_ELEMENT) {
  286.                 ACPI_WARN_PREDEFINED((AE_INFO, info->full_pathname,
  287.                                       info->node_flags,
  288.                                       "Return type mismatch - found %s, expected %s",
  289.                                       acpi_ut_get_object_type_name
  290.                                       (return_object), type_buffer));
  291.         } else {
  292.                 ACPI_WARN_PREDEFINED((AE_INFO, info->full_pathname,
  293.                                       info->node_flags,
  294.                                       "Return Package type mismatch at index %u - "
  295.                                       "found %s, expected %s", package_index,
  296.                                       acpi_ut_get_object_type_name
  297.                                       (return_object), type_buffer));
  298.         }
  299.  
  300.         return (AE_AML_OPERAND_TYPE);
  301. }
  302.  
  303. /*******************************************************************************
  304.  *
  305.  * FUNCTION:    acpi_ns_check_reference
  306.  *
  307.  * PARAMETERS:  info            - Method execution information block
  308.  *              return_object   - Object returned from the evaluation of a
  309.  *                                method or object
  310.  *
  311.  * RETURN:      Status
  312.  *
  313.  * DESCRIPTION: Check a returned reference object for the correct reference
  314.  *              type. The only reference type that can be returned from a
  315.  *              predefined method is a named reference. All others are invalid.
  316.  *
  317.  ******************************************************************************/
  318.  
  319. static acpi_status
  320. acpi_ns_check_reference(struct acpi_evaluate_info *info,
  321.                         union acpi_operand_object *return_object)
  322. {
  323.  
  324.         /*
  325.          * Check the reference object for the correct reference type (opcode).
  326.          * The only type of reference that can be converted to an union acpi_object is
  327.          * a reference to a named object (reference class: NAME)
  328.          */
  329.         if (return_object->reference.class == ACPI_REFCLASS_NAME) {
  330.                 return (AE_OK);
  331.         }
  332.  
  333.         ACPI_WARN_PREDEFINED((AE_INFO, info->full_pathname, info->node_flags,
  334.                               "Return type mismatch - unexpected reference object type [%s] %2.2X",
  335.                               acpi_ut_get_reference_name(return_object),
  336.                               return_object->reference.class));
  337.  
  338.         return (AE_AML_OPERAND_TYPE);
  339. }
  340.  
  341. /*******************************************************************************
  342.  *
  343.  * FUNCTION:    acpi_ns_get_bitmapped_type
  344.  *
  345.  * PARAMETERS:  return_object   - Object returned from method/obj evaluation
  346.  *
  347.  * RETURN:      Object return type. ACPI_RTYPE_ANY indicates that the object
  348.  *              type is not supported. ACPI_RTYPE_NONE indicates that no
  349.  *              object was returned (return_object is NULL).
  350.  *
  351.  * DESCRIPTION: Convert object type into a bitmapped object return type.
  352.  *
  353.  ******************************************************************************/
  354.  
  355. static u32 acpi_ns_get_bitmapped_type(union acpi_operand_object *return_object)
  356. {
  357.         u32 return_btype;
  358.  
  359.         if (!return_object) {
  360.                 return (ACPI_RTYPE_NONE);
  361.         }
  362.  
  363.         /* Map acpi_object_type to internal bitmapped type */
  364.  
  365.         switch (return_object->common.type) {
  366.         case ACPI_TYPE_INTEGER:
  367.  
  368.                 return_btype = ACPI_RTYPE_INTEGER;
  369.                 break;
  370.  
  371.         case ACPI_TYPE_BUFFER:
  372.  
  373.                 return_btype = ACPI_RTYPE_BUFFER;
  374.                 break;
  375.  
  376.         case ACPI_TYPE_STRING:
  377.  
  378.                 return_btype = ACPI_RTYPE_STRING;
  379.                 break;
  380.  
  381.         case ACPI_TYPE_PACKAGE:
  382.  
  383.                 return_btype = ACPI_RTYPE_PACKAGE;
  384.                 break;
  385.  
  386.         case ACPI_TYPE_LOCAL_REFERENCE:
  387.  
  388.                 return_btype = ACPI_RTYPE_REFERENCE;
  389.                 break;
  390.  
  391.         default:
  392.  
  393.                 /* Not one of the supported objects, must be incorrect */
  394.  
  395.                 return_btype = ACPI_RTYPE_ANY;
  396.                 break;
  397.         }
  398.  
  399.         return (return_btype);
  400. }
  401.