root/drivers/acpi/acpica/dsargs.c

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

DEFINITIONS

This source file includes following definitions.
  1. ACPI_MODULE_NAME
  2. acpi_ds_get_buffer_field_arguments
  3. acpi_ds_get_bank_field_arguments
  4. acpi_ds_get_buffer_arguments
  5. acpi_ds_get_package_arguments
  6. acpi_ds_get_region_arguments

   1 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
   2 /******************************************************************************
   3  *
   4  * Module Name: dsargs - Support for execution of dynamic arguments for static
   5  *                       objects (regions, fields, buffer fields, etc.)
   6  *
   7  * Copyright (C) 2000 - 2019, Intel Corp.
   8  *
   9  *****************************************************************************/
  10 
  11 #include <acpi/acpi.h>
  12 #include "accommon.h"
  13 #include "acparser.h"
  14 #include "amlcode.h"
  15 #include "acdispat.h"
  16 #include "acnamesp.h"
  17 
  18 #define _COMPONENT          ACPI_DISPATCHER
  19 ACPI_MODULE_NAME("dsargs")
  20 
  21 /* Local prototypes */
  22 static acpi_status
  23 acpi_ds_execute_arguments(struct acpi_namespace_node *node,
  24                           struct acpi_namespace_node *scope_node,
  25                           u32 aml_length, u8 *aml_start);
  26 
  27 /*******************************************************************************
  28  *
  29  * FUNCTION:    acpi_ds_execute_arguments
  30  *
  31  * PARAMETERS:  node                - Object NS node
  32  *              scope_node          - Parent NS node
  33  *              aml_length          - Length of executable AML
  34  *              aml_start           - Pointer to the AML
  35  *
  36  * RETURN:      Status.
  37  *
  38  * DESCRIPTION: Late (deferred) execution of region or field arguments
  39  *
  40  ******************************************************************************/
  41 
  42 static acpi_status
  43 acpi_ds_execute_arguments(struct acpi_namespace_node *node,
  44                           struct acpi_namespace_node *scope_node,
  45                           u32 aml_length, u8 *aml_start)
  46 {
  47         acpi_status status;
  48         union acpi_parse_object *op;
  49         struct acpi_walk_state *walk_state;
  50 
  51         ACPI_FUNCTION_TRACE_PTR(ds_execute_arguments, aml_start);
  52 
  53         /* Allocate a new parser op to be the root of the parsed tree */
  54 
  55         op = acpi_ps_alloc_op(AML_INT_EVAL_SUBTREE_OP, aml_start);
  56         if (!op) {
  57                 return_ACPI_STATUS(AE_NO_MEMORY);
  58         }
  59 
  60         /* Save the Node for use in acpi_ps_parse_aml */
  61 
  62         op->common.node = scope_node;
  63 
  64         /* Create and initialize a new parser state */
  65 
  66         walk_state = acpi_ds_create_walk_state(0, NULL, NULL, NULL);
  67         if (!walk_state) {
  68                 status = AE_NO_MEMORY;
  69                 goto cleanup;
  70         }
  71 
  72         status = acpi_ds_init_aml_walk(walk_state, op, NULL, aml_start,
  73                                        aml_length, NULL, ACPI_IMODE_LOAD_PASS1);
  74         if (ACPI_FAILURE(status)) {
  75                 acpi_ds_delete_walk_state(walk_state);
  76                 goto cleanup;
  77         }
  78 
  79         /* Mark this parse as a deferred opcode */
  80 
  81         walk_state->parse_flags = ACPI_PARSE_DEFERRED_OP;
  82         walk_state->deferred_node = node;
  83 
  84         /* Pass1: Parse the entire declaration */
  85 
  86         status = acpi_ps_parse_aml(walk_state);
  87         if (ACPI_FAILURE(status)) {
  88                 goto cleanup;
  89         }
  90 
  91         /* Get and init the Op created above */
  92 
  93         op->common.node = node;
  94         acpi_ps_delete_parse_tree(op);
  95 
  96         /* Evaluate the deferred arguments */
  97 
  98         op = acpi_ps_alloc_op(AML_INT_EVAL_SUBTREE_OP, aml_start);
  99         if (!op) {
 100                 return_ACPI_STATUS(AE_NO_MEMORY);
 101         }
 102 
 103         op->common.node = scope_node;
 104 
 105         /* Create and initialize a new parser state */
 106 
 107         walk_state = acpi_ds_create_walk_state(0, NULL, NULL, NULL);
 108         if (!walk_state) {
 109                 status = AE_NO_MEMORY;
 110                 goto cleanup;
 111         }
 112 
 113         /* Execute the opcode and arguments */
 114 
 115         status = acpi_ds_init_aml_walk(walk_state, op, NULL, aml_start,
 116                                        aml_length, NULL, ACPI_IMODE_EXECUTE);
 117         if (ACPI_FAILURE(status)) {
 118                 acpi_ds_delete_walk_state(walk_state);
 119                 goto cleanup;
 120         }
 121 
 122         /* Mark this execution as a deferred opcode */
 123 
 124         walk_state->deferred_node = node;
 125         status = acpi_ps_parse_aml(walk_state);
 126 
 127 cleanup:
 128         acpi_ps_delete_parse_tree(op);
 129         return_ACPI_STATUS(status);
 130 }
 131 
 132 /*******************************************************************************
 133  *
 134  * FUNCTION:    acpi_ds_get_buffer_field_arguments
 135  *
 136  * PARAMETERS:  obj_desc        - A valid buffer_field object
 137  *
 138  * RETURN:      Status.
 139  *
 140  * DESCRIPTION: Get buffer_field Buffer and Index. This implements the late
 141  *              evaluation of these field attributes.
 142  *
 143  ******************************************************************************/
 144 
 145 acpi_status
 146 acpi_ds_get_buffer_field_arguments(union acpi_operand_object *obj_desc)
 147 {
 148         union acpi_operand_object *extra_desc;
 149         struct acpi_namespace_node *node;
 150         acpi_status status;
 151 
 152         ACPI_FUNCTION_TRACE_PTR(ds_get_buffer_field_arguments, obj_desc);
 153 
 154         if (obj_desc->common.flags & AOPOBJ_DATA_VALID) {
 155                 return_ACPI_STATUS(AE_OK);
 156         }
 157 
 158         /* Get the AML pointer (method object) and buffer_field node */
 159 
 160         extra_desc = acpi_ns_get_secondary_object(obj_desc);
 161         node = obj_desc->buffer_field.node;
 162 
 163         ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname
 164                         (ACPI_TYPE_BUFFER_FIELD, node, NULL));
 165 
 166         ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "[%4.4s] BufferField Arg Init\n",
 167                           acpi_ut_get_node_name(node)));
 168 
 169         /* Execute the AML code for the term_arg arguments */
 170 
 171         status = acpi_ds_execute_arguments(node, node->parent,
 172                                            extra_desc->extra.aml_length,
 173                                            extra_desc->extra.aml_start);
 174         return_ACPI_STATUS(status);
 175 }
 176 
 177 /*******************************************************************************
 178  *
 179  * FUNCTION:    acpi_ds_get_bank_field_arguments
 180  *
 181  * PARAMETERS:  obj_desc        - A valid bank_field object
 182  *
 183  * RETURN:      Status.
 184  *
 185  * DESCRIPTION: Get bank_field bank_value. This implements the late
 186  *              evaluation of these field attributes.
 187  *
 188  ******************************************************************************/
 189 
 190 acpi_status
 191 acpi_ds_get_bank_field_arguments(union acpi_operand_object *obj_desc)
 192 {
 193         union acpi_operand_object *extra_desc;
 194         struct acpi_namespace_node *node;
 195         acpi_status status;
 196 
 197         ACPI_FUNCTION_TRACE_PTR(ds_get_bank_field_arguments, obj_desc);
 198 
 199         if (obj_desc->common.flags & AOPOBJ_DATA_VALID) {
 200                 return_ACPI_STATUS(AE_OK);
 201         }
 202 
 203         /* Get the AML pointer (method object) and bank_field node */
 204 
 205         extra_desc = acpi_ns_get_secondary_object(obj_desc);
 206         node = obj_desc->bank_field.node;
 207 
 208         ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname
 209                         (ACPI_TYPE_LOCAL_BANK_FIELD, node, NULL));
 210 
 211         ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "[%4.4s] BankField Arg Init\n",
 212                           acpi_ut_get_node_name(node)));
 213 
 214         /* Execute the AML code for the term_arg arguments */
 215 
 216         status = acpi_ds_execute_arguments(node, node->parent,
 217                                            extra_desc->extra.aml_length,
 218                                            extra_desc->extra.aml_start);
 219         if (ACPI_FAILURE(status)) {
 220                 return_ACPI_STATUS(status);
 221         }
 222 
 223         status = acpi_ut_add_address_range(obj_desc->region.space_id,
 224                                            obj_desc->region.address,
 225                                            obj_desc->region.length, node);
 226         return_ACPI_STATUS(status);
 227 }
 228 
 229 /*******************************************************************************
 230  *
 231  * FUNCTION:    acpi_ds_get_buffer_arguments
 232  *
 233  * PARAMETERS:  obj_desc        - A valid Buffer object
 234  *
 235  * RETURN:      Status.
 236  *
 237  * DESCRIPTION: Get Buffer length and initializer byte list. This implements
 238  *              the late evaluation of these attributes.
 239  *
 240  ******************************************************************************/
 241 
 242 acpi_status acpi_ds_get_buffer_arguments(union acpi_operand_object *obj_desc)
 243 {
 244         struct acpi_namespace_node *node;
 245         acpi_status status;
 246 
 247         ACPI_FUNCTION_TRACE_PTR(ds_get_buffer_arguments, obj_desc);
 248 
 249         if (obj_desc->common.flags & AOPOBJ_DATA_VALID) {
 250                 return_ACPI_STATUS(AE_OK);
 251         }
 252 
 253         /* Get the Buffer node */
 254 
 255         node = obj_desc->buffer.node;
 256         if (!node) {
 257                 ACPI_ERROR((AE_INFO,
 258                             "No pointer back to namespace node in buffer object %p",
 259                             obj_desc));
 260                 return_ACPI_STATUS(AE_AML_INTERNAL);
 261         }
 262 
 263         ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Buffer Arg Init\n"));
 264 
 265         /* Execute the AML code for the term_arg arguments */
 266 
 267         status = acpi_ds_execute_arguments(node, node,
 268                                            obj_desc->buffer.aml_length,
 269                                            obj_desc->buffer.aml_start);
 270         return_ACPI_STATUS(status);
 271 }
 272 
 273 /*******************************************************************************
 274  *
 275  * FUNCTION:    acpi_ds_get_package_arguments
 276  *
 277  * PARAMETERS:  obj_desc        - A valid Package object
 278  *
 279  * RETURN:      Status.
 280  *
 281  * DESCRIPTION: Get Package length and initializer byte list. This implements
 282  *              the late evaluation of these attributes.
 283  *
 284  ******************************************************************************/
 285 
 286 acpi_status acpi_ds_get_package_arguments(union acpi_operand_object *obj_desc)
 287 {
 288         struct acpi_namespace_node *node;
 289         acpi_status status;
 290 
 291         ACPI_FUNCTION_TRACE_PTR(ds_get_package_arguments, obj_desc);
 292 
 293         if (obj_desc->common.flags & AOPOBJ_DATA_VALID) {
 294                 return_ACPI_STATUS(AE_OK);
 295         }
 296 
 297         /* Get the Package node */
 298 
 299         node = obj_desc->package.node;
 300         if (!node) {
 301                 ACPI_ERROR((AE_INFO,
 302                             "No pointer back to namespace node in package %p",
 303                             obj_desc));
 304                 return_ACPI_STATUS(AE_AML_INTERNAL);
 305         }
 306 
 307         ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Package Argument Init, AML Ptr: %p\n",
 308                           obj_desc->package.aml_start));
 309 
 310         /* Execute the AML code for the term_arg arguments */
 311 
 312         status = acpi_ds_execute_arguments(node, node,
 313                                            obj_desc->package.aml_length,
 314                                            obj_desc->package.aml_start);
 315 
 316         return_ACPI_STATUS(status);
 317 }
 318 
 319 /*******************************************************************************
 320  *
 321  * FUNCTION:    acpi_ds_get_region_arguments
 322  *
 323  * PARAMETERS:  obj_desc        - A valid region object
 324  *
 325  * RETURN:      Status.
 326  *
 327  * DESCRIPTION: Get region address and length. This implements the late
 328  *              evaluation of these region attributes.
 329  *
 330  ******************************************************************************/
 331 
 332 acpi_status acpi_ds_get_region_arguments(union acpi_operand_object *obj_desc)
 333 {
 334         struct acpi_namespace_node *node;
 335         acpi_status status;
 336         union acpi_operand_object *extra_desc;
 337 
 338         ACPI_FUNCTION_TRACE_PTR(ds_get_region_arguments, obj_desc);
 339 
 340         if (obj_desc->region.flags & AOPOBJ_DATA_VALID) {
 341                 return_ACPI_STATUS(AE_OK);
 342         }
 343 
 344         extra_desc = acpi_ns_get_secondary_object(obj_desc);
 345         if (!extra_desc) {
 346                 return_ACPI_STATUS(AE_NOT_EXIST);
 347         }
 348 
 349         /* Get the Region node */
 350 
 351         node = obj_desc->region.node;
 352 
 353         ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname
 354                         (ACPI_TYPE_REGION, node, NULL));
 355 
 356         ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
 357                           "[%4.4s] OpRegion Arg Init at AML %p\n",
 358                           acpi_ut_get_node_name(node),
 359                           extra_desc->extra.aml_start));
 360 
 361         /* Execute the argument AML */
 362 
 363         status = acpi_ds_execute_arguments(node, extra_desc->extra.scope_node,
 364                                            extra_desc->extra.aml_length,
 365                                            extra_desc->extra.aml_start);
 366         if (ACPI_FAILURE(status)) {
 367                 return_ACPI_STATUS(status);
 368         }
 369 
 370         status = acpi_ut_add_address_range(obj_desc->region.space_id,
 371                                            obj_desc->region.address,
 372                                            obj_desc->region.length, node);
 373         return_ACPI_STATUS(status);
 374 }

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