LCOV - code coverage report
Current view: top level - drivers/acpi/acpica - nseval.c (source / functions) Hit Total Coverage
Test: combined.info Lines: 53 71 74.6 %
Date: 2022-04-01 14:17:54 Functions: 1 1 100.0 %
Branches: 18 31 58.1 %

           Branch data     Line data    Source code
       1                 :            : // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
       2                 :            : /*******************************************************************************
       3                 :            :  *
       4                 :            :  * Module Name: nseval - Object evaluation, includes control method execution
       5                 :            :  *
       6                 :            :  ******************************************************************************/
       7                 :            : 
       8                 :            : #include <acpi/acpi.h>
       9                 :            : #include "accommon.h"
      10                 :            : #include "acparser.h"
      11                 :            : #include "acinterp.h"
      12                 :            : #include "acnamesp.h"
      13                 :            : 
      14                 :            : #define _COMPONENT          ACPI_NAMESPACE
      15                 :            : ACPI_MODULE_NAME("nseval")
      16                 :            : 
      17                 :            : /*******************************************************************************
      18                 :            :  *
      19                 :            :  * FUNCTION:    acpi_ns_evaluate
      20                 :            :  *
      21                 :            :  * PARAMETERS:  info            - Evaluation info block, contains these fields
      22                 :            :  *                                and more:
      23                 :            :  *                  prefix_node     - Prefix or Method/Object Node to execute
      24                 :            :  *                  relative_path   - Name of method to execute, If NULL, the
      25                 :            :  *                                    Node is the object to execute
      26                 :            :  *                  parameters      - List of parameters to pass to the method,
      27                 :            :  *                                    terminated by NULL. Params itself may be
      28                 :            :  *                                    NULL if no parameters are being passed.
      29                 :            :  *                  parameter_type  - Type of Parameter list
      30                 :            :  *                  return_object   - Where to put method's return value (if
      31                 :            :  *                                    any). If NULL, no value is returned.
      32                 :            :  *                  flags           - ACPI_IGNORE_RETURN_VALUE to delete return
      33                 :            :  *
      34                 :            :  * RETURN:      Status
      35                 :            :  *
      36                 :            :  * DESCRIPTION: Execute a control method or return the current value of an
      37                 :            :  *              ACPI namespace object.
      38                 :            :  *
      39                 :            :  * MUTEX:       Locks interpreter
      40                 :            :  *
      41                 :            :  ******************************************************************************/
      42                 :      27467 : acpi_status acpi_ns_evaluate(struct acpi_evaluate_info *info)
      43                 :            : {
      44                 :      27467 :         acpi_status status;
      45                 :            : 
      46                 :      27467 :         ACPI_FUNCTION_TRACE(ns_evaluate);
      47                 :            : 
      48         [ +  - ]:      27467 :         if (!info) {
      49                 :            :                 return_ACPI_STATUS(AE_BAD_PARAMETER);
      50                 :            :         }
      51                 :            : 
      52         [ +  - ]:      27467 :         if (!info->node) {
      53                 :            :                 /*
      54                 :            :                  * Get the actual namespace node for the target object if we
      55                 :            :                  * need to. Handles these cases:
      56                 :            :                  *
      57                 :            :                  * 1) Null node, valid pathname from root (absolute path)
      58                 :            :                  * 2) Node and valid pathname (path relative to Node)
      59                 :            :                  * 3) Node, Null pathname
      60                 :            :                  */
      61                 :      27467 :                 status =
      62                 :      27467 :                     acpi_ns_get_node(info->prefix_node, info->relative_pathname,
      63                 :            :                                      ACPI_NS_NO_UPSEARCH, &info->node);
      64         [ +  + ]:      27467 :                 if (ACPI_FAILURE(status)) {
      65                 :            :                         return_ACPI_STATUS(status);
      66                 :            :                 }
      67                 :            :         }
      68                 :            : 
      69                 :            :         /*
      70                 :            :          * For a method alias, we must grab the actual method node so that
      71                 :            :          * proper scoping context will be established before execution.
      72                 :            :          */
      73         [ -  + ]:       6754 :         if (acpi_ns_get_type(info->node) == ACPI_TYPE_LOCAL_METHOD_ALIAS) {
      74                 :          0 :                 info->node =
      75                 :          0 :                     ACPI_CAST_PTR(struct acpi_namespace_node,
      76                 :            :                                   info->node->object);
      77                 :            :         }
      78                 :            : 
      79                 :            :         /* Complete the info block initialization */
      80                 :            : 
      81                 :       6754 :         info->return_object = NULL;
      82                 :       6754 :         info->node_flags = info->node->flags;
      83                 :       6754 :         info->obj_desc = acpi_ns_get_attached_object(info->node);
      84                 :            : 
      85                 :            :         ACPI_DEBUG_PRINT((ACPI_DB_NAMES, "%s [%p] Value %p\n",
      86                 :            :                           info->relative_pathname, info->node,
      87                 :       6754 :                           acpi_ns_get_attached_object(info->node)));
      88                 :            : 
      89                 :            :         /* Get info if we have a predefined name (_HID, etc.) */
      90                 :            : 
      91                 :      13508 :         info->predefined =
      92                 :       6754 :             acpi_ut_match_predefined_method(info->node->name.ascii);
      93                 :            : 
      94                 :            :         /* Get the full pathname to the object, for use in warning messages */
      95                 :            : 
      96                 :       6754 :         info->full_pathname = acpi_ns_get_normalized_pathname(info->node, TRUE);
      97         [ +  - ]:       6754 :         if (!info->full_pathname) {
      98                 :            :                 return_ACPI_STATUS(AE_NO_MEMORY);
      99                 :            :         }
     100                 :            : 
     101                 :            :         /* Optional object evaluation log */
     102                 :            : 
     103                 :            :         ACPI_DEBUG_PRINT_RAW((ACPI_DB_EVALUATION,
     104                 :            :                               "%-26s:  %s (%s)\n", "   Enter evaluation",
     105                 :            :                               &info->full_pathname[1],
     106                 :       6754 :                               acpi_ut_get_type_name(info->node->type)));
     107                 :            : 
     108                 :            :         /* Count the number of arguments being passed in */
     109                 :            : 
     110                 :       6754 :         info->param_count = 0;
     111         [ +  + ]:       6754 :         if (info->parameters) {
     112         [ +  + ]:         22 :                 while (info->parameters[info->param_count]) {
     113                 :         11 :                         info->param_count++;
     114                 :            :                 }
     115                 :            : 
     116                 :            :                 /* Warn on impossible argument count */
     117                 :            : 
     118         [ -  + ]:         11 :                 if (info->param_count > ACPI_METHOD_NUM_ARGS) {
     119                 :          0 :                         ACPI_WARN_PREDEFINED((AE_INFO, info->full_pathname,
     120                 :            :                                               ACPI_WARN_ALWAYS,
     121                 :            :                                               "Excess arguments (%u) - using only %u",
     122                 :            :                                               info->param_count,
     123                 :            :                                               ACPI_METHOD_NUM_ARGS));
     124                 :            : 
     125                 :          0 :                         info->param_count = ACPI_METHOD_NUM_ARGS;
     126                 :            :                 }
     127                 :            :         }
     128                 :            : 
     129                 :            :         /*
     130                 :            :          * For predefined names: Check that the declared argument count
     131                 :            :          * matches the ACPI spec -- otherwise this is a BIOS error.
     132                 :            :          */
     133                 :       6754 :         acpi_ns_check_acpi_compliance(info->full_pathname, info->node,
     134                 :            :                                       info->predefined);
     135                 :            : 
     136                 :            :         /*
     137                 :            :          * For all names: Check that the incoming argument count for
     138                 :            :          * this method/object matches the actual ASL/AML definition.
     139                 :            :          */
     140                 :       6754 :         acpi_ns_check_argument_count(info->full_pathname, info->node,
     141                 :       6754 :                                      info->param_count, info->predefined);
     142                 :            : 
     143                 :            :         /* For predefined names: Typecheck all incoming arguments */
     144                 :            : 
     145                 :       6754 :         acpi_ns_check_argument_types(info);
     146                 :            : 
     147                 :            :         /*
     148                 :            :          * Three major evaluation cases:
     149                 :            :          *
     150                 :            :          * 1) Object types that cannot be evaluated by definition
     151                 :            :          * 2) The object is a control method -- execute it
     152                 :            :          * 3) The object is not a method -- just return it's current value
     153                 :            :          */
     154      [ -  +  + ]:       6754 :         switch (acpi_ns_get_type(info->node)) {
     155                 :          0 :         case ACPI_TYPE_ANY:
     156                 :            :         case ACPI_TYPE_DEVICE:
     157                 :            :         case ACPI_TYPE_EVENT:
     158                 :            :         case ACPI_TYPE_MUTEX:
     159                 :            :         case ACPI_TYPE_REGION:
     160                 :            :         case ACPI_TYPE_THERMAL:
     161                 :            :         case ACPI_TYPE_LOCAL_SCOPE:
     162                 :            :                 /*
     163                 :            :                  * 1) Disallow evaluation of these object types. For these,
     164                 :            :                  *    object evaluation is undefined.
     165                 :            :                  */
     166                 :          0 :                 ACPI_ERROR((AE_INFO,
     167                 :            :                             "%s: This object type [%s] "
     168                 :            :                             "never contains data and cannot be evaluated",
     169                 :            :                             info->full_pathname,
     170                 :            :                             acpi_ut_get_type_name(info->node->type)));
     171                 :            : 
     172                 :          0 :                 status = AE_TYPE;
     173                 :          0 :                 goto cleanup;
     174                 :            : 
     175                 :        803 :         case ACPI_TYPE_METHOD:
     176                 :            :                 /*
     177                 :            :                  * 2) Object is a control method - execute it
     178                 :            :                  */
     179                 :            : 
     180                 :            :                 /* Verify that there is a method object associated with this node */
     181                 :            : 
     182         [ -  + ]:        803 :                 if (!info->obj_desc) {
     183                 :          0 :                         ACPI_ERROR((AE_INFO,
     184                 :            :                                     "%s: Method has no attached sub-object",
     185                 :            :                                     info->full_pathname));
     186                 :          0 :                         status = AE_NULL_OBJECT;
     187                 :          0 :                         goto cleanup;
     188                 :            :                 }
     189                 :            : 
     190                 :            :                 ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
     191                 :            :                                   "**** Execute method [%s] at AML address %p length %X\n",
     192                 :            :                                   info->full_pathname,
     193                 :            :                                   info->obj_desc->method.aml_start + 1,
     194                 :        803 :                                   info->obj_desc->method.aml_length - 1));
     195                 :            : 
     196                 :            :                 /*
     197                 :            :                  * Any namespace deletion must acquire both the namespace and
     198                 :            :                  * interpreter locks to ensure that no thread is using the portion of
     199                 :            :                  * the namespace that is being deleted.
     200                 :            :                  *
     201                 :            :                  * Execute the method via the interpreter. The interpreter is locked
     202                 :            :                  * here before calling into the AML parser
     203                 :            :                  */
     204                 :        803 :                 acpi_ex_enter_interpreter();
     205                 :        803 :                 status = acpi_ps_execute_method(info);
     206                 :        803 :                 acpi_ex_exit_interpreter();
     207                 :        803 :                 break;
     208                 :            : 
     209                 :       5951 :         default:
     210                 :            :                 /*
     211                 :            :                  * 3) All other non-method objects -- get the current object value
     212                 :            :                  */
     213                 :            : 
     214                 :            :                 /*
     215                 :            :                  * Some objects require additional resolution steps (e.g., the Node
     216                 :            :                  * may be a field that must be read, etc.) -- we can't just grab
     217                 :            :                  * the object out of the node.
     218                 :            :                  *
     219                 :            :                  * Use resolve_node_to_value() to get the associated value.
     220                 :            :                  *
     221                 :            :                  * NOTE: we can get away with passing in NULL for a walk state because
     222                 :            :                  * the Node is guaranteed to not be a reference to either a method
     223                 :            :                  * local or a method argument (because this interface is never called
     224                 :            :                  * from a running method.)
     225                 :            :                  *
     226                 :            :                  * Even though we do not directly invoke the interpreter for object
     227                 :            :                  * resolution, we must lock it because we could access an op_region.
     228                 :            :                  * The op_region access code assumes that the interpreter is locked.
     229                 :            :                  */
     230                 :       5951 :                 acpi_ex_enter_interpreter();
     231                 :            : 
     232                 :            :                 /* TBD: resolve_node_to_value has a strange interface, fix */
     233                 :            : 
     234                 :       5951 :                 info->return_object =
     235                 :       5951 :                     ACPI_CAST_PTR(union acpi_operand_object, info->node);
     236                 :            : 
     237                 :       5951 :                 status =
     238                 :       5951 :                     acpi_ex_resolve_node_to_value(ACPI_CAST_INDIRECT_PTR
     239                 :            :                                                   (struct acpi_namespace_node,
     240                 :            :                                                    &info->return_object), NULL);
     241                 :       5951 :                 acpi_ex_exit_interpreter();
     242                 :            : 
     243         [ -  + ]:       5951 :                 if (ACPI_FAILURE(status)) {
     244                 :          0 :                         info->return_object = NULL;
     245                 :          0 :                         goto cleanup;
     246                 :            :                 }
     247                 :            : 
     248                 :            :                 ACPI_DEBUG_PRINT((ACPI_DB_NAMES, "Returned object %p [%s]\n",
     249                 :            :                                   info->return_object,
     250                 :            :                                   acpi_ut_get_object_type_name(info->
     251                 :            :                                                                return_object)));
     252                 :            : 
     253                 :            :                 status = AE_CTRL_RETURN_VALUE;  /* Always has a "return value" */
     254                 :            :                 break;
     255                 :            :         }
     256                 :            : 
     257                 :            :         /*
     258                 :            :          * For predefined names, check the return value against the ACPI
     259                 :            :          * specification. Some incorrect return value types are repaired.
     260                 :            :          */
     261                 :       6754 :         (void)acpi_ns_check_return_value(info->node, info, info->param_count,
     262                 :            :                                          status, &info->return_object);
     263                 :            : 
     264                 :            :         /* Check if there is a return value that must be dealt with */
     265                 :            : 
     266         [ +  - ]:       6754 :         if (status == AE_CTRL_RETURN_VALUE) {
     267                 :            : 
     268                 :            :                 /* If caller does not want the return value, delete it */
     269                 :            : 
     270         [ +  + ]:       6754 :                 if (info->flags & ACPI_IGNORE_RETURN_VALUE) {
     271                 :         22 :                         acpi_ut_remove_reference(info->return_object);
     272                 :         22 :                         info->return_object = NULL;
     273                 :            :                 }
     274                 :            : 
     275                 :            :                 /* Map AE_CTRL_RETURN_VALUE to AE_OK, we are done with it */
     276                 :            : 
     277                 :            :                 status = AE_OK;
     278         [ #  # ]:          0 :         } else if (ACPI_FAILURE(status)) {
     279                 :            : 
     280                 :            :                 /* If return_object exists, delete it */
     281                 :            : 
     282         [ #  # ]:          0 :                 if (info->return_object) {
     283                 :          0 :                         acpi_ut_remove_reference(info->return_object);
     284                 :          0 :                         info->return_object = NULL;
     285                 :            :                 }
     286                 :            :         }
     287                 :            : 
     288                 :            :         ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
     289                 :            :                           "*** Completed evaluation of object %s ***\n",
     290                 :       6754 :                           info->relative_pathname));
     291                 :            : 
     292                 :          0 : cleanup:
     293                 :            :         /* Optional object evaluation log */
     294                 :            : 
     295                 :            :         ACPI_DEBUG_PRINT_RAW((ACPI_DB_EVALUATION,
     296                 :            :                               "%-26s:  %s\n", "   Exit evaluation",
     297                 :       6754 :                               &info->full_pathname[1]));
     298                 :            : 
     299                 :            :         /*
     300                 :            :          * Namespace was unlocked by the handling acpi_ns* function, so we
     301                 :            :          * just free the pathname and return
     302                 :            :          */
     303                 :       6754 :         ACPI_FREE(info->full_pathname);
     304                 :       6754 :         info->full_pathname = NULL;
     305                 :       6754 :         return_ACPI_STATUS(status);
     306                 :            : }

Generated by: LCOV version 1.14