root/drivers/acpi/acpica/psxface.c

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

DEFINITIONS

This source file includes following definitions.
  1. ACPI_MODULE_NAME
  2. acpi_ps_execute_method
  3. acpi_ps_execute_table
  4. acpi_ps_update_parameter_list

   1 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
   2 /******************************************************************************
   3  *
   4  * Module Name: psxface - Parser external interfaces
   5  *
   6  * Copyright (C) 2000 - 2019, Intel Corp.
   7  *
   8  *****************************************************************************/
   9 
  10 #include <acpi/acpi.h>
  11 #include "accommon.h"
  12 #include "acparser.h"
  13 #include "acdispat.h"
  14 #include "acinterp.h"
  15 #include "actables.h"
  16 #include "acnamesp.h"
  17 
  18 #define _COMPONENT          ACPI_PARSER
  19 ACPI_MODULE_NAME("psxface")
  20 
  21 /* Local Prototypes */
  22 static void
  23 acpi_ps_update_parameter_list(struct acpi_evaluate_info *info, u16 action);
  24 
  25 /*******************************************************************************
  26  *
  27  * FUNCTION:    acpi_debug_trace
  28  *
  29  * PARAMETERS:  method_name     - Valid ACPI name string
  30  *              debug_level     - Optional level mask. 0 to use default
  31  *              debug_layer     - Optional layer mask. 0 to use default
  32  *              flags           - bit 1: one shot(1) or persistent(0)
  33  *
  34  * RETURN:      Status
  35  *
  36  * DESCRIPTION: External interface to enable debug tracing during control
  37  *              method execution
  38  *
  39  ******************************************************************************/
  40 
  41 acpi_status
  42 acpi_debug_trace(const char *name, u32 debug_level, u32 debug_layer, u32 flags)
  43 {
  44         acpi_status status;
  45 
  46         status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
  47         if (ACPI_FAILURE(status)) {
  48                 return (status);
  49         }
  50 
  51         acpi_gbl_trace_method_name = name;
  52         acpi_gbl_trace_flags = flags;
  53         acpi_gbl_trace_dbg_level = debug_level;
  54         acpi_gbl_trace_dbg_layer = debug_layer;
  55         status = AE_OK;
  56 
  57         (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
  58         return (status);
  59 }
  60 
  61 /*******************************************************************************
  62  *
  63  * FUNCTION:    acpi_ps_execute_method
  64  *
  65  * PARAMETERS:  info            - Method info block, contains:
  66  *                  node            - Method Node to execute
  67  *                  obj_desc        - Method object
  68  *                  parameters      - List of parameters to pass to the method,
  69  *                                    terminated by NULL. Params itself may be
  70  *                                    NULL if no parameters are being passed.
  71  *                  return_object   - Where to put method's return value (if
  72  *                                    any). If NULL, no value is returned.
  73  *                  parameter_type  - Type of Parameter list
  74  *                  return_object   - Where to put method's return value (if
  75  *                                    any). If NULL, no value is returned.
  76  *                  pass_number     - Parse or execute pass
  77  *
  78  * RETURN:      Status
  79  *
  80  * DESCRIPTION: Execute a control method
  81  *
  82  ******************************************************************************/
  83 
  84 acpi_status acpi_ps_execute_method(struct acpi_evaluate_info *info)
  85 {
  86         acpi_status status;
  87         union acpi_parse_object *op;
  88         struct acpi_walk_state *walk_state;
  89 
  90         ACPI_FUNCTION_TRACE(ps_execute_method);
  91 
  92         /* Quick validation of DSDT header */
  93 
  94         acpi_tb_check_dsdt_header();
  95 
  96         /* Validate the Info and method Node */
  97 
  98         if (!info || !info->node) {
  99                 return_ACPI_STATUS(AE_NULL_ENTRY);
 100         }
 101 
 102         /* Init for new method, wait on concurrency semaphore */
 103 
 104         status =
 105             acpi_ds_begin_method_execution(info->node, info->obj_desc, NULL);
 106         if (ACPI_FAILURE(status)) {
 107                 return_ACPI_STATUS(status);
 108         }
 109 
 110         /*
 111          * The caller "owns" the parameters, so give each one an extra reference
 112          */
 113         acpi_ps_update_parameter_list(info, REF_INCREMENT);
 114 
 115         /*
 116          * Execute the method. Performs parse simultaneously
 117          */
 118         ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
 119                           "**** Begin Method Parse/Execute [%4.4s] **** Node=%p Obj=%p\n",
 120                           info->node->name.ascii, info->node, info->obj_desc));
 121 
 122         /* Create and init a Root Node */
 123 
 124         op = acpi_ps_create_scope_op(info->obj_desc->method.aml_start);
 125         if (!op) {
 126                 status = AE_NO_MEMORY;
 127                 goto cleanup;
 128         }
 129 
 130         /* Create and initialize a new walk state */
 131 
 132         info->pass_number = ACPI_IMODE_EXECUTE;
 133         walk_state =
 134             acpi_ds_create_walk_state(info->obj_desc->method.owner_id, NULL,
 135                                       NULL, NULL);
 136         if (!walk_state) {
 137                 status = AE_NO_MEMORY;
 138                 goto cleanup;
 139         }
 140 
 141         status = acpi_ds_init_aml_walk(walk_state, op, info->node,
 142                                        info->obj_desc->method.aml_start,
 143                                        info->obj_desc->method.aml_length, info,
 144                                        info->pass_number);
 145         if (ACPI_FAILURE(status)) {
 146                 acpi_ds_delete_walk_state(walk_state);
 147                 goto cleanup;
 148         }
 149 
 150         walk_state->method_pathname = info->full_pathname;
 151         walk_state->method_is_nested = FALSE;
 152 
 153         if (info->obj_desc->method.info_flags & ACPI_METHOD_MODULE_LEVEL) {
 154                 walk_state->parse_flags |= ACPI_PARSE_MODULE_LEVEL;
 155         }
 156 
 157         /* Invoke an internal method if necessary */
 158 
 159         if (info->obj_desc->method.info_flags & ACPI_METHOD_INTERNAL_ONLY) {
 160                 status =
 161                     info->obj_desc->method.dispatch.implementation(walk_state);
 162                 info->return_object = walk_state->return_desc;
 163 
 164                 /* Cleanup states */
 165 
 166                 acpi_ds_scope_stack_clear(walk_state);
 167                 acpi_ps_cleanup_scope(&walk_state->parser_state);
 168                 acpi_ds_terminate_control_method(walk_state->method_desc,
 169                                                  walk_state);
 170                 acpi_ds_delete_walk_state(walk_state);
 171                 goto cleanup;
 172         }
 173 
 174         /*
 175          * Start method evaluation with an implicit return of zero.
 176          * This is done for Windows compatibility.
 177          */
 178         if (acpi_gbl_enable_interpreter_slack) {
 179                 walk_state->implicit_return_obj =
 180                     acpi_ut_create_integer_object((u64) 0);
 181                 if (!walk_state->implicit_return_obj) {
 182                         status = AE_NO_MEMORY;
 183                         acpi_ds_delete_walk_state(walk_state);
 184                         goto cleanup;
 185                 }
 186         }
 187 
 188         /* Parse the AML */
 189 
 190         status = acpi_ps_parse_aml(walk_state);
 191 
 192         /* walk_state was deleted by parse_aml */
 193 
 194 cleanup:
 195         acpi_ps_delete_parse_tree(op);
 196 
 197         /* Take away the extra reference that we gave the parameters above */
 198 
 199         acpi_ps_update_parameter_list(info, REF_DECREMENT);
 200 
 201         /* Exit now if error above */
 202 
 203         if (ACPI_FAILURE(status)) {
 204                 return_ACPI_STATUS(status);
 205         }
 206 
 207         /*
 208          * If the method has returned an object, signal this to the caller with
 209          * a control exception code
 210          */
 211         if (info->return_object) {
 212                 ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "Method returned ObjDesc=%p\n",
 213                                   info->return_object));
 214                 ACPI_DUMP_STACK_ENTRY(info->return_object);
 215 
 216                 status = AE_CTRL_RETURN_VALUE;
 217         }
 218 
 219         return_ACPI_STATUS(status);
 220 }
 221 
 222 /*******************************************************************************
 223  *
 224  * FUNCTION:    acpi_ps_execute_table
 225  *
 226  * PARAMETERS:  info            - Method info block, contains:
 227  *              node            - Node to where the is entered into the
 228  *                                namespace
 229  *              obj_desc        - Pseudo method object describing the AML
 230  *                                code of the entire table
 231  *              pass_number     - Parse or execute pass
 232  *
 233  * RETURN:      Status
 234  *
 235  * DESCRIPTION: Execute a table
 236  *
 237  ******************************************************************************/
 238 
 239 acpi_status acpi_ps_execute_table(struct acpi_evaluate_info *info)
 240 {
 241         acpi_status status;
 242         union acpi_parse_object *op = NULL;
 243         struct acpi_walk_state *walk_state = NULL;
 244 
 245         ACPI_FUNCTION_TRACE(ps_execute_table);
 246 
 247         /* Create and init a Root Node */
 248 
 249         op = acpi_ps_create_scope_op(info->obj_desc->method.aml_start);
 250         if (!op) {
 251                 status = AE_NO_MEMORY;
 252                 goto cleanup;
 253         }
 254 
 255         /* Create and initialize a new walk state */
 256 
 257         walk_state =
 258             acpi_ds_create_walk_state(info->obj_desc->method.owner_id, NULL,
 259                                       NULL, NULL);
 260         if (!walk_state) {
 261                 status = AE_NO_MEMORY;
 262                 goto cleanup;
 263         }
 264 
 265         status = acpi_ds_init_aml_walk(walk_state, op, info->node,
 266                                        info->obj_desc->method.aml_start,
 267                                        info->obj_desc->method.aml_length, info,
 268                                        info->pass_number);
 269         if (ACPI_FAILURE(status)) {
 270                 goto cleanup;
 271         }
 272 
 273         walk_state->method_pathname = info->full_pathname;
 274         walk_state->method_is_nested = FALSE;
 275 
 276         if (info->obj_desc->method.info_flags & ACPI_METHOD_MODULE_LEVEL) {
 277                 walk_state->parse_flags |= ACPI_PARSE_MODULE_LEVEL;
 278         }
 279 
 280         /* Info->Node is the default location to load the table  */
 281 
 282         if (info->node && info->node != acpi_gbl_root_node) {
 283                 status =
 284                     acpi_ds_scope_stack_push(info->node, ACPI_TYPE_METHOD,
 285                                              walk_state);
 286                 if (ACPI_FAILURE(status)) {
 287                         goto cleanup;
 288                 }
 289         }
 290 
 291         /*
 292          * Parse the AML, walk_state will be deleted by parse_aml
 293          */
 294         acpi_ex_enter_interpreter();
 295         status = acpi_ps_parse_aml(walk_state);
 296         acpi_ex_exit_interpreter();
 297         walk_state = NULL;
 298 
 299 cleanup:
 300         if (walk_state) {
 301                 acpi_ds_delete_walk_state(walk_state);
 302         }
 303         if (op) {
 304                 acpi_ps_delete_parse_tree(op);
 305         }
 306         return_ACPI_STATUS(status);
 307 }
 308 
 309 /*******************************************************************************
 310  *
 311  * FUNCTION:    acpi_ps_update_parameter_list
 312  *
 313  * PARAMETERS:  info            - See struct acpi_evaluate_info
 314  *                                (Used: parameter_type and Parameters)
 315  *              action          - Add or Remove reference
 316  *
 317  * RETURN:      Status
 318  *
 319  * DESCRIPTION: Update reference count on all method parameter objects
 320  *
 321  ******************************************************************************/
 322 
 323 static void
 324 acpi_ps_update_parameter_list(struct acpi_evaluate_info *info, u16 action)
 325 {
 326         u32 i;
 327 
 328         if (info->parameters) {
 329 
 330                 /* Update reference count for each parameter */
 331 
 332                 for (i = 0; info->parameters[i]; i++) {
 333 
 334                         /* Ignore errors, just do them all */
 335 
 336                         (void)acpi_ut_update_object_reference(info->
 337                                                               parameters[i],
 338                                                               action);
 339                 }
 340         }
 341 }

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