root/drivers/acpi/acpica/dsopcode.c

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

DEFINITIONS

This source file includes following definitions.
  1. ACPI_MODULE_NAME
  2. acpi_ds_init_buffer_field
  3. acpi_ds_eval_buffer_field_operands
  4. acpi_ds_eval_region_operands
  5. acpi_ds_eval_table_region_operands
  6. acpi_ds_eval_data_object_operands
  7. acpi_ds_eval_bank_field_operands

   1 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
   2 /******************************************************************************
   3  *
   4  * Module Name: dsopcode - Dispatcher support for regions and fields
   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 "amlcode.h"
  14 #include "acdispat.h"
  15 #include "acinterp.h"
  16 #include "acnamesp.h"
  17 #include "acevents.h"
  18 #include "actables.h"
  19 
  20 #define _COMPONENT          ACPI_DISPATCHER
  21 ACPI_MODULE_NAME("dsopcode")
  22 
  23 /* Local prototypes */
  24 static acpi_status
  25 acpi_ds_init_buffer_field(u16 aml_opcode,
  26                           union acpi_operand_object *obj_desc,
  27                           union acpi_operand_object *buffer_desc,
  28                           union acpi_operand_object *offset_desc,
  29                           union acpi_operand_object *length_desc,
  30                           union acpi_operand_object *result_desc);
  31 
  32 /*******************************************************************************
  33  *
  34  * FUNCTION:    acpi_ds_initialize_region
  35  *
  36  * PARAMETERS:  obj_handle      - Region namespace node
  37  *
  38  * RETURN:      Status
  39  *
  40  * DESCRIPTION: Front end to ev_initialize_region
  41  *
  42  ******************************************************************************/
  43 
  44 acpi_status acpi_ds_initialize_region(acpi_handle obj_handle)
  45 {
  46         union acpi_operand_object *obj_desc;
  47         acpi_status status;
  48 
  49         obj_desc = acpi_ns_get_attached_object(obj_handle);
  50 
  51         /* Namespace is NOT locked */
  52 
  53         status = acpi_ev_initialize_region(obj_desc);
  54         return (status);
  55 }
  56 
  57 /*******************************************************************************
  58  *
  59  * FUNCTION:    acpi_ds_init_buffer_field
  60  *
  61  * PARAMETERS:  aml_opcode      - create_xxx_field
  62  *              obj_desc        - buffer_field object
  63  *              buffer_desc     - Host Buffer
  64  *              offset_desc     - Offset into buffer
  65  *              length_desc     - Length of field (CREATE_FIELD_OP only)
  66  *              result_desc     - Where to store the result
  67  *
  68  * RETURN:      Status
  69  *
  70  * DESCRIPTION: Perform actual initialization of a buffer field
  71  *
  72  ******************************************************************************/
  73 
  74 static acpi_status
  75 acpi_ds_init_buffer_field(u16 aml_opcode,
  76                           union acpi_operand_object *obj_desc,
  77                           union acpi_operand_object *buffer_desc,
  78                           union acpi_operand_object *offset_desc,
  79                           union acpi_operand_object *length_desc,
  80                           union acpi_operand_object *result_desc)
  81 {
  82         u32 offset;
  83         u32 bit_offset;
  84         u32 bit_count;
  85         u8 field_flags;
  86         acpi_status status;
  87 
  88         ACPI_FUNCTION_TRACE_PTR(ds_init_buffer_field, obj_desc);
  89 
  90         /* Host object must be a Buffer */
  91 
  92         if (buffer_desc->common.type != ACPI_TYPE_BUFFER) {
  93                 ACPI_ERROR((AE_INFO,
  94                             "Target of Create Field is not a Buffer object - %s",
  95                             acpi_ut_get_object_type_name(buffer_desc)));
  96 
  97                 status = AE_AML_OPERAND_TYPE;
  98                 goto cleanup;
  99         }
 100 
 101         /*
 102          * The last parameter to all of these opcodes (result_desc) started
 103          * out as a name_string, and should therefore now be a NS node
 104          * after resolution in acpi_ex_resolve_operands().
 105          */
 106         if (ACPI_GET_DESCRIPTOR_TYPE(result_desc) != ACPI_DESC_TYPE_NAMED) {
 107                 ACPI_ERROR((AE_INFO,
 108                             "(%s) destination not a NS Node [%s]",
 109                             acpi_ps_get_opcode_name(aml_opcode),
 110                             acpi_ut_get_descriptor_name(result_desc)));
 111 
 112                 status = AE_AML_OPERAND_TYPE;
 113                 goto cleanup;
 114         }
 115 
 116         offset = (u32) offset_desc->integer.value;
 117 
 118         /*
 119          * Setup the Bit offsets and counts, according to the opcode
 120          */
 121         switch (aml_opcode) {
 122         case AML_CREATE_FIELD_OP:
 123 
 124                 /* Offset is in bits, count is in bits */
 125 
 126                 field_flags = AML_FIELD_ACCESS_BYTE;
 127                 bit_offset = offset;
 128                 bit_count = (u32) length_desc->integer.value;
 129 
 130                 /* Must have a valid (>0) bit count */
 131 
 132                 if (bit_count == 0) {
 133                         ACPI_BIOS_ERROR((AE_INFO,
 134                                          "Attempt to CreateField of length zero"));
 135                         status = AE_AML_OPERAND_VALUE;
 136                         goto cleanup;
 137                 }
 138                 break;
 139 
 140         case AML_CREATE_BIT_FIELD_OP:
 141 
 142                 /* Offset is in bits, Field is one bit */
 143 
 144                 bit_offset = offset;
 145                 bit_count = 1;
 146                 field_flags = AML_FIELD_ACCESS_BYTE;
 147                 break;
 148 
 149         case AML_CREATE_BYTE_FIELD_OP:
 150 
 151                 /* Offset is in bytes, field is one byte */
 152 
 153                 bit_offset = 8 * offset;
 154                 bit_count = 8;
 155                 field_flags = AML_FIELD_ACCESS_BYTE;
 156                 break;
 157 
 158         case AML_CREATE_WORD_FIELD_OP:
 159 
 160                 /* Offset is in bytes, field is one word */
 161 
 162                 bit_offset = 8 * offset;
 163                 bit_count = 16;
 164                 field_flags = AML_FIELD_ACCESS_WORD;
 165                 break;
 166 
 167         case AML_CREATE_DWORD_FIELD_OP:
 168 
 169                 /* Offset is in bytes, field is one dword */
 170 
 171                 bit_offset = 8 * offset;
 172                 bit_count = 32;
 173                 field_flags = AML_FIELD_ACCESS_DWORD;
 174                 break;
 175 
 176         case AML_CREATE_QWORD_FIELD_OP:
 177 
 178                 /* Offset is in bytes, field is one qword */
 179 
 180                 bit_offset = 8 * offset;
 181                 bit_count = 64;
 182                 field_flags = AML_FIELD_ACCESS_QWORD;
 183                 break;
 184 
 185         default:
 186 
 187                 ACPI_ERROR((AE_INFO,
 188                             "Unknown field creation opcode 0x%02X",
 189                             aml_opcode));
 190                 status = AE_AML_BAD_OPCODE;
 191                 goto cleanup;
 192         }
 193 
 194         /* Entire field must fit within the current length of the buffer */
 195 
 196         if ((bit_offset + bit_count) > (8 * (u32)buffer_desc->buffer.length)) {
 197                 status = AE_AML_BUFFER_LIMIT;
 198                 ACPI_BIOS_EXCEPTION((AE_INFO, status,
 199                                      "Field [%4.4s] at bit offset/length %u/%u "
 200                                      "exceeds size of target Buffer (%u bits)",
 201                                      acpi_ut_get_node_name(result_desc),
 202                                      bit_offset, bit_count,
 203                                      8 * (u32)buffer_desc->buffer.length));
 204                 goto cleanup;
 205         }
 206 
 207         /*
 208          * Initialize areas of the field object that are common to all fields
 209          * For field_flags, use LOCK_RULE = 0 (NO_LOCK),
 210          * UPDATE_RULE = 0 (UPDATE_PRESERVE)
 211          */
 212         status =
 213             acpi_ex_prep_common_field_object(obj_desc, field_flags, 0,
 214                                              bit_offset, bit_count);
 215         if (ACPI_FAILURE(status)) {
 216                 goto cleanup;
 217         }
 218 
 219         obj_desc->buffer_field.buffer_obj = buffer_desc;
 220 
 221         /* Reference count for buffer_desc inherits obj_desc count */
 222 
 223         buffer_desc->common.reference_count = (u16)
 224             (buffer_desc->common.reference_count +
 225              obj_desc->common.reference_count);
 226 
 227 cleanup:
 228 
 229         /* Always delete the operands */
 230 
 231         acpi_ut_remove_reference(offset_desc);
 232         acpi_ut_remove_reference(buffer_desc);
 233 
 234         if (aml_opcode == AML_CREATE_FIELD_OP) {
 235                 acpi_ut_remove_reference(length_desc);
 236         }
 237 
 238         /* On failure, delete the result descriptor */
 239 
 240         if (ACPI_FAILURE(status)) {
 241                 acpi_ut_remove_reference(result_desc);  /* Result descriptor */
 242         } else {
 243                 /* Now the address and length are valid for this buffer_field */
 244 
 245                 obj_desc->buffer_field.flags |= AOPOBJ_DATA_VALID;
 246         }
 247 
 248         return_ACPI_STATUS(status);
 249 }
 250 
 251 /*******************************************************************************
 252  *
 253  * FUNCTION:    acpi_ds_eval_buffer_field_operands
 254  *
 255  * PARAMETERS:  walk_state      - Current walk
 256  *              op              - A valid buffer_field Op object
 257  *
 258  * RETURN:      Status
 259  *
 260  * DESCRIPTION: Get buffer_field Buffer and Index
 261  *              Called from acpi_ds_exec_end_op during buffer_field parse tree walk
 262  *
 263  ******************************************************************************/
 264 
 265 acpi_status
 266 acpi_ds_eval_buffer_field_operands(struct acpi_walk_state *walk_state,
 267                                    union acpi_parse_object *op)
 268 {
 269         acpi_status status;
 270         union acpi_operand_object *obj_desc;
 271         struct acpi_namespace_node *node;
 272         union acpi_parse_object *next_op;
 273 
 274         ACPI_FUNCTION_TRACE_PTR(ds_eval_buffer_field_operands, op);
 275 
 276         /*
 277          * This is where we evaluate the address and length fields of the
 278          * create_xxx_field declaration
 279          */
 280         node = op->common.node;
 281 
 282         /* next_op points to the op that holds the Buffer */
 283 
 284         next_op = op->common.value.arg;
 285 
 286         /* Evaluate/create the address and length operands */
 287 
 288         status = acpi_ds_create_operands(walk_state, next_op);
 289         if (ACPI_FAILURE(status)) {
 290                 return_ACPI_STATUS(status);
 291         }
 292 
 293         obj_desc = acpi_ns_get_attached_object(node);
 294         if (!obj_desc) {
 295                 return_ACPI_STATUS(AE_NOT_EXIST);
 296         }
 297 
 298         /* Resolve the operands */
 299 
 300         status =
 301             acpi_ex_resolve_operands(op->common.aml_opcode, ACPI_WALK_OPERANDS,
 302                                      walk_state);
 303         if (ACPI_FAILURE(status)) {
 304                 ACPI_ERROR((AE_INFO, "(%s) bad operand(s), status 0x%X",
 305                             acpi_ps_get_opcode_name(op->common.aml_opcode),
 306                             status));
 307 
 308                 return_ACPI_STATUS(status);
 309         }
 310 
 311         /* Initialize the Buffer Field */
 312 
 313         if (op->common.aml_opcode == AML_CREATE_FIELD_OP) {
 314 
 315                 /* NOTE: Slightly different operands for this opcode */
 316 
 317                 status =
 318                     acpi_ds_init_buffer_field(op->common.aml_opcode, obj_desc,
 319                                               walk_state->operands[0],
 320                                               walk_state->operands[1],
 321                                               walk_state->operands[2],
 322                                               walk_state->operands[3]);
 323         } else {
 324                 /* All other, create_xxx_field opcodes */
 325 
 326                 status =
 327                     acpi_ds_init_buffer_field(op->common.aml_opcode, obj_desc,
 328                                               walk_state->operands[0],
 329                                               walk_state->operands[1], NULL,
 330                                               walk_state->operands[2]);
 331         }
 332 
 333         return_ACPI_STATUS(status);
 334 }
 335 
 336 /*******************************************************************************
 337  *
 338  * FUNCTION:    acpi_ds_eval_region_operands
 339  *
 340  * PARAMETERS:  walk_state      - Current walk
 341  *              op              - A valid region Op object
 342  *
 343  * RETURN:      Status
 344  *
 345  * DESCRIPTION: Get region address and length
 346  *              Called from acpi_ds_exec_end_op during op_region parse tree walk
 347  *
 348  ******************************************************************************/
 349 
 350 acpi_status
 351 acpi_ds_eval_region_operands(struct acpi_walk_state *walk_state,
 352                              union acpi_parse_object *op)
 353 {
 354         acpi_status status;
 355         union acpi_operand_object *obj_desc;
 356         union acpi_operand_object *operand_desc;
 357         struct acpi_namespace_node *node;
 358         union acpi_parse_object *next_op;
 359         acpi_adr_space_type space_id;
 360 
 361         ACPI_FUNCTION_TRACE_PTR(ds_eval_region_operands, op);
 362 
 363         /*
 364          * This is where we evaluate the address and length fields of the
 365          * op_region declaration
 366          */
 367         node = op->common.node;
 368 
 369         /* next_op points to the op that holds the space_ID */
 370 
 371         next_op = op->common.value.arg;
 372         space_id = (acpi_adr_space_type)next_op->common.value.integer;
 373 
 374         /* next_op points to address op */
 375 
 376         next_op = next_op->common.next;
 377 
 378         /* Evaluate/create the address and length operands */
 379 
 380         status = acpi_ds_create_operands(walk_state, next_op);
 381         if (ACPI_FAILURE(status)) {
 382                 return_ACPI_STATUS(status);
 383         }
 384 
 385         /* Resolve the length and address operands to numbers */
 386 
 387         status =
 388             acpi_ex_resolve_operands(op->common.aml_opcode, ACPI_WALK_OPERANDS,
 389                                      walk_state);
 390         if (ACPI_FAILURE(status)) {
 391                 return_ACPI_STATUS(status);
 392         }
 393 
 394         obj_desc = acpi_ns_get_attached_object(node);
 395         if (!obj_desc) {
 396                 return_ACPI_STATUS(AE_NOT_EXIST);
 397         }
 398 
 399         /*
 400          * Get the length operand and save it
 401          * (at Top of stack)
 402          */
 403         operand_desc = walk_state->operands[walk_state->num_operands - 1];
 404 
 405         obj_desc->region.length = (u32) operand_desc->integer.value;
 406         acpi_ut_remove_reference(operand_desc);
 407 
 408         /* A zero-length operation region is unusable. Just warn */
 409 
 410         if (!obj_desc->region.length
 411             && (space_id < ACPI_NUM_PREDEFINED_REGIONS)) {
 412                 ACPI_WARNING((AE_INFO,
 413                               "Operation Region [%4.4s] has zero length (SpaceId %X)",
 414                               node->name.ascii, space_id));
 415         }
 416 
 417         /*
 418          * Get the address and save it
 419          * (at top of stack - 1)
 420          */
 421         operand_desc = walk_state->operands[walk_state->num_operands - 2];
 422 
 423         obj_desc->region.address = (acpi_physical_address)
 424             operand_desc->integer.value;
 425         acpi_ut_remove_reference(operand_desc);
 426 
 427         ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "RgnObj %p Addr %8.8X%8.8X Len %X\n",
 428                           obj_desc,
 429                           ACPI_FORMAT_UINT64(obj_desc->region.address),
 430                           obj_desc->region.length));
 431 
 432         status = acpi_ut_add_address_range(obj_desc->region.space_id,
 433                                            obj_desc->region.address,
 434                                            obj_desc->region.length, node);
 435 
 436         /* Now the address and length are valid for this opregion */
 437 
 438         obj_desc->region.flags |= AOPOBJ_DATA_VALID;
 439         return_ACPI_STATUS(status);
 440 }
 441 
 442 /*******************************************************************************
 443  *
 444  * FUNCTION:    acpi_ds_eval_table_region_operands
 445  *
 446  * PARAMETERS:  walk_state      - Current walk
 447  *              op              - A valid region Op object
 448  *
 449  * RETURN:      Status
 450  *
 451  * DESCRIPTION: Get region address and length.
 452  *              Called from acpi_ds_exec_end_op during data_table_region parse
 453  *              tree walk.
 454  *
 455  ******************************************************************************/
 456 
 457 acpi_status
 458 acpi_ds_eval_table_region_operands(struct acpi_walk_state *walk_state,
 459                                    union acpi_parse_object *op)
 460 {
 461         acpi_status status;
 462         union acpi_operand_object *obj_desc;
 463         union acpi_operand_object **operand;
 464         struct acpi_namespace_node *node;
 465         union acpi_parse_object *next_op;
 466         struct acpi_table_header *table;
 467         u32 table_index;
 468 
 469         ACPI_FUNCTION_TRACE_PTR(ds_eval_table_region_operands, op);
 470 
 471         /*
 472          * This is where we evaluate the Signature string, oem_id string,
 473          * and oem_table_id string of the Data Table Region declaration
 474          */
 475         node = op->common.node;
 476 
 477         /* next_op points to Signature string op */
 478 
 479         next_op = op->common.value.arg;
 480 
 481         /*
 482          * Evaluate/create the Signature string, oem_id string,
 483          * and oem_table_id string operands
 484          */
 485         status = acpi_ds_create_operands(walk_state, next_op);
 486         if (ACPI_FAILURE(status)) {
 487                 return_ACPI_STATUS(status);
 488         }
 489 
 490         operand = &walk_state->operands[0];
 491 
 492         /*
 493          * Resolve the Signature string, oem_id string,
 494          * and oem_table_id string operands
 495          */
 496         status =
 497             acpi_ex_resolve_operands(op->common.aml_opcode, ACPI_WALK_OPERANDS,
 498                                      walk_state);
 499         if (ACPI_FAILURE(status)) {
 500                 goto cleanup;
 501         }
 502 
 503         /* Find the ACPI table */
 504 
 505         status = acpi_tb_find_table(operand[0]->string.pointer,
 506                                     operand[1]->string.pointer,
 507                                     operand[2]->string.pointer, &table_index);
 508         if (ACPI_FAILURE(status)) {
 509                 if (status == AE_NOT_FOUND) {
 510                         ACPI_ERROR((AE_INFO,
 511                                     "ACPI Table [%4.4s] OEM:(%s, %s) not found in RSDT/XSDT",
 512                                     operand[0]->string.pointer,
 513                                     operand[1]->string.pointer,
 514                                     operand[2]->string.pointer));
 515                 }
 516                 goto cleanup;
 517         }
 518 
 519         status = acpi_get_table_by_index(table_index, &table);
 520         if (ACPI_FAILURE(status)) {
 521                 goto cleanup;
 522         }
 523 
 524         obj_desc = acpi_ns_get_attached_object(node);
 525         if (!obj_desc) {
 526                 status = AE_NOT_EXIST;
 527                 goto cleanup;
 528         }
 529 
 530         obj_desc->region.address = ACPI_PTR_TO_PHYSADDR(table);
 531         obj_desc->region.length = table->length;
 532 
 533         ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "RgnObj %p Addr %8.8X%8.8X Len %X\n",
 534                           obj_desc,
 535                           ACPI_FORMAT_UINT64(obj_desc->region.address),
 536                           obj_desc->region.length));
 537 
 538         /* Now the address and length are valid for this opregion */
 539 
 540         obj_desc->region.flags |= AOPOBJ_DATA_VALID;
 541 
 542 cleanup:
 543         acpi_ut_remove_reference(operand[0]);
 544         acpi_ut_remove_reference(operand[1]);
 545         acpi_ut_remove_reference(operand[2]);
 546 
 547         return_ACPI_STATUS(status);
 548 }
 549 
 550 /*******************************************************************************
 551  *
 552  * FUNCTION:    acpi_ds_eval_data_object_operands
 553  *
 554  * PARAMETERS:  walk_state      - Current walk
 555  *              op              - A valid data_object Op object
 556  *              obj_desc        - data_object
 557  *
 558  * RETURN:      Status
 559  *
 560  * DESCRIPTION: Get the operands and complete the following data object types:
 561  *              Buffer, Package.
 562  *
 563  ******************************************************************************/
 564 
 565 acpi_status
 566 acpi_ds_eval_data_object_operands(struct acpi_walk_state *walk_state,
 567                                   union acpi_parse_object *op,
 568                                   union acpi_operand_object *obj_desc)
 569 {
 570         acpi_status status;
 571         union acpi_operand_object *arg_desc;
 572         u32 length;
 573 
 574         ACPI_FUNCTION_TRACE(ds_eval_data_object_operands);
 575 
 576         /* The first operand (for all of these data objects) is the length */
 577 
 578         /*
 579          * Set proper index into operand stack for acpi_ds_obj_stack_push
 580          * invoked inside acpi_ds_create_operand.
 581          */
 582         walk_state->operand_index = walk_state->num_operands;
 583 
 584         /* Ignore if child is not valid */
 585 
 586         if (!op->common.value.arg) {
 587                 ACPI_ERROR((AE_INFO,
 588                             "Missing child while evaluating opcode %4.4X, Op %p",
 589                             op->common.aml_opcode, op));
 590                 return_ACPI_STATUS(AE_OK);
 591         }
 592 
 593         status = acpi_ds_create_operand(walk_state, op->common.value.arg, 1);
 594         if (ACPI_FAILURE(status)) {
 595                 return_ACPI_STATUS(status);
 596         }
 597 
 598         status = acpi_ex_resolve_operands(walk_state->opcode,
 599                                           &(walk_state->
 600                                             operands[walk_state->num_operands -
 601                                                      1]), walk_state);
 602         if (ACPI_FAILURE(status)) {
 603                 return_ACPI_STATUS(status);
 604         }
 605 
 606         /* Extract length operand */
 607 
 608         arg_desc = walk_state->operands[walk_state->num_operands - 1];
 609         length = (u32) arg_desc->integer.value;
 610 
 611         /* Cleanup for length operand */
 612 
 613         status = acpi_ds_obj_stack_pop(1, walk_state);
 614         if (ACPI_FAILURE(status)) {
 615                 return_ACPI_STATUS(status);
 616         }
 617 
 618         acpi_ut_remove_reference(arg_desc);
 619 
 620         /*
 621          * Create the actual data object
 622          */
 623         switch (op->common.aml_opcode) {
 624         case AML_BUFFER_OP:
 625 
 626                 status =
 627                     acpi_ds_build_internal_buffer_obj(walk_state, op, length,
 628                                                       &obj_desc);
 629                 break;
 630 
 631         case AML_PACKAGE_OP:
 632         case AML_VARIABLE_PACKAGE_OP:
 633 
 634                 status =
 635                     acpi_ds_build_internal_package_obj(walk_state, op, length,
 636                                                        &obj_desc);
 637                 break;
 638 
 639         default:
 640 
 641                 return_ACPI_STATUS(AE_AML_BAD_OPCODE);
 642         }
 643 
 644         if (ACPI_SUCCESS(status)) {
 645                 /*
 646                  * Return the object in the walk_state, unless the parent is a package -
 647                  * in this case, the return object will be stored in the parse tree
 648                  * for the package.
 649                  */
 650                 if ((!op->common.parent) ||
 651                     ((op->common.parent->common.aml_opcode != AML_PACKAGE_OP) &&
 652                      (op->common.parent->common.aml_opcode !=
 653                       AML_VARIABLE_PACKAGE_OP)
 654                      && (op->common.parent->common.aml_opcode !=
 655                          AML_NAME_OP))) {
 656                         walk_state->result_obj = obj_desc;
 657                 }
 658         }
 659 
 660         return_ACPI_STATUS(status);
 661 }
 662 
 663 /*******************************************************************************
 664  *
 665  * FUNCTION:    acpi_ds_eval_bank_field_operands
 666  *
 667  * PARAMETERS:  walk_state      - Current walk
 668  *              op              - A valid bank_field Op object
 669  *
 670  * RETURN:      Status
 671  *
 672  * DESCRIPTION: Get bank_field bank_value
 673  *              Called from acpi_ds_exec_end_op during bank_field parse tree walk
 674  *
 675  ******************************************************************************/
 676 
 677 acpi_status
 678 acpi_ds_eval_bank_field_operands(struct acpi_walk_state *walk_state,
 679                                  union acpi_parse_object *op)
 680 {
 681         acpi_status status;
 682         union acpi_operand_object *obj_desc;
 683         union acpi_operand_object *operand_desc;
 684         struct acpi_namespace_node *node;
 685         union acpi_parse_object *next_op;
 686         union acpi_parse_object *arg;
 687 
 688         ACPI_FUNCTION_TRACE_PTR(ds_eval_bank_field_operands, op);
 689 
 690         /*
 691          * This is where we evaluate the bank_value field of the
 692          * bank_field declaration
 693          */
 694 
 695         /* next_op points to the op that holds the Region */
 696 
 697         next_op = op->common.value.arg;
 698 
 699         /* next_op points to the op that holds the Bank Register */
 700 
 701         next_op = next_op->common.next;
 702 
 703         /* next_op points to the op that holds the Bank Value */
 704 
 705         next_op = next_op->common.next;
 706 
 707         /*
 708          * Set proper index into operand stack for acpi_ds_obj_stack_push
 709          * invoked inside acpi_ds_create_operand.
 710          *
 711          * We use walk_state->Operands[0] to store the evaluated bank_value
 712          */
 713         walk_state->operand_index = 0;
 714 
 715         status = acpi_ds_create_operand(walk_state, next_op, 0);
 716         if (ACPI_FAILURE(status)) {
 717                 return_ACPI_STATUS(status);
 718         }
 719 
 720         status = acpi_ex_resolve_to_value(&walk_state->operands[0], walk_state);
 721         if (ACPI_FAILURE(status)) {
 722                 return_ACPI_STATUS(status);
 723         }
 724 
 725         ACPI_DUMP_OPERANDS(ACPI_WALK_OPERANDS,
 726                            acpi_ps_get_opcode_name(op->common.aml_opcode), 1);
 727         /*
 728          * Get the bank_value operand and save it
 729          * (at Top of stack)
 730          */
 731         operand_desc = walk_state->operands[0];
 732 
 733         /* Arg points to the start Bank Field */
 734 
 735         arg = acpi_ps_get_arg(op, 4);
 736         while (arg) {
 737 
 738                 /* Ignore OFFSET and ACCESSAS terms here */
 739 
 740                 if (arg->common.aml_opcode == AML_INT_NAMEDFIELD_OP) {
 741                         node = arg->common.node;
 742 
 743                         obj_desc = acpi_ns_get_attached_object(node);
 744                         if (!obj_desc) {
 745                                 return_ACPI_STATUS(AE_NOT_EXIST);
 746                         }
 747 
 748                         obj_desc->bank_field.value =
 749                             (u32) operand_desc->integer.value;
 750                 }
 751 
 752                 /* Move to next field in the list */
 753 
 754                 arg = arg->common.next;
 755         }
 756 
 757         acpi_ut_remove_reference(operand_desc);
 758         return_ACPI_STATUS(status);
 759 }

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