root/drivers/acpi/acpica/dsfield.c

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

DEFINITIONS

This source file includes following definitions.
  1. ACPI_MODULE_NAME
  2. acpi_ds_create_buffer_field
  3. acpi_ds_get_field_names
  4. acpi_ds_create_field
  5. acpi_ds_init_field_objects
  6. acpi_ds_create_bank_field
  7. acpi_ds_create_index_field

   1 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
   2 /******************************************************************************
   3  *
   4  * Module Name: dsfield - Dispatcher field routines
   5  *
   6  * Copyright (C) 2000 - 2019, Intel Corp.
   7  *
   8  *****************************************************************************/
   9 
  10 #include <acpi/acpi.h>
  11 #include "accommon.h"
  12 #include "amlcode.h"
  13 #include "acdispat.h"
  14 #include "acinterp.h"
  15 #include "acnamesp.h"
  16 #include "acparser.h"
  17 
  18 #ifdef ACPI_EXEC_APP
  19 #include "aecommon.h"
  20 #endif
  21 
  22 #define _COMPONENT          ACPI_DISPATCHER
  23 ACPI_MODULE_NAME("dsfield")
  24 
  25 /* Local prototypes */
  26 #ifdef ACPI_ASL_COMPILER
  27 #include "acdisasm.h"
  28 static acpi_status
  29 acpi_ds_create_external_region(acpi_status lookup_status,
  30                                union acpi_parse_object *op,
  31                                char *path,
  32                                struct acpi_walk_state *walk_state,
  33                                struct acpi_namespace_node **node);
  34 #endif
  35 
  36 static acpi_status
  37 acpi_ds_get_field_names(struct acpi_create_field_info *info,
  38                         struct acpi_walk_state *walk_state,
  39                         union acpi_parse_object *arg);
  40 
  41 #ifdef ACPI_ASL_COMPILER
  42 /*******************************************************************************
  43  *
  44  * FUNCTION:    acpi_ds_create_external_region (iASL Disassembler only)
  45  *
  46  * PARAMETERS:  lookup_status   - Status from ns_lookup operation
  47  *              op              - Op containing the Field definition and args
  48  *              path            - Pathname of the region
  49  *  `           walk_state      - Current method state
  50  *              node            - Where the new region node is returned
  51  *
  52  * RETURN:      Status
  53  *
  54  * DESCRIPTION: Add region to the external list if NOT_FOUND. Create a new
  55  *              region node/object.
  56  *
  57  ******************************************************************************/
  58 
  59 static acpi_status
  60 acpi_ds_create_external_region(acpi_status lookup_status,
  61                                union acpi_parse_object *op,
  62                                char *path,
  63                                struct acpi_walk_state *walk_state,
  64                                struct acpi_namespace_node **node)
  65 {
  66         acpi_status status;
  67         union acpi_operand_object *obj_desc;
  68 
  69         if (lookup_status != AE_NOT_FOUND) {
  70                 return (lookup_status);
  71         }
  72 
  73         /*
  74          * Table disassembly:
  75          * operation_region not found. Generate an External for it, and
  76          * insert the name into the namespace.
  77          */
  78         acpi_dm_add_op_to_external_list(op, path, ACPI_TYPE_REGION, 0, 0);
  79 
  80         status = acpi_ns_lookup(walk_state->scope_info, path, ACPI_TYPE_REGION,
  81                                 ACPI_IMODE_LOAD_PASS1, ACPI_NS_SEARCH_PARENT,
  82                                 walk_state, node);
  83         if (ACPI_FAILURE(status)) {
  84                 return (status);
  85         }
  86 
  87         /* Must create and install a region object for the new node */
  88 
  89         obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_REGION);
  90         if (!obj_desc) {
  91                 return (AE_NO_MEMORY);
  92         }
  93 
  94         obj_desc->region.node = *node;
  95         status = acpi_ns_attach_object(*node, obj_desc, ACPI_TYPE_REGION);
  96         return (status);
  97 }
  98 #endif
  99 
 100 /*******************************************************************************
 101  *
 102  * FUNCTION:    acpi_ds_create_buffer_field
 103  *
 104  * PARAMETERS:  op                  - Current parse op (create_XXField)
 105  *              walk_state          - Current state
 106  *
 107  * RETURN:      Status
 108  *
 109  * DESCRIPTION: Execute the create_field operators:
 110  *              create_bit_field_op,
 111  *              create_byte_field_op,
 112  *              create_word_field_op,
 113  *              create_dword_field_op,
 114  *              create_qword_field_op,
 115  *              create_field_op     (all of which define a field in a buffer)
 116  *
 117  ******************************************************************************/
 118 
 119 acpi_status
 120 acpi_ds_create_buffer_field(union acpi_parse_object *op,
 121                             struct acpi_walk_state *walk_state)
 122 {
 123         union acpi_parse_object *arg;
 124         struct acpi_namespace_node *node;
 125         acpi_status status;
 126         union acpi_operand_object *obj_desc;
 127         union acpi_operand_object *second_desc = NULL;
 128         u32 flags;
 129 
 130         ACPI_FUNCTION_TRACE(ds_create_buffer_field);
 131 
 132         /*
 133          * Get the name_string argument (name of the new buffer_field)
 134          */
 135         if (op->common.aml_opcode == AML_CREATE_FIELD_OP) {
 136 
 137                 /* For create_field, name is the 4th argument */
 138 
 139                 arg = acpi_ps_get_arg(op, 3);
 140         } else {
 141                 /* For all other create_XXXField operators, name is the 3rd argument */
 142 
 143                 arg = acpi_ps_get_arg(op, 2);
 144         }
 145 
 146         if (!arg) {
 147                 return_ACPI_STATUS(AE_AML_NO_OPERAND);
 148         }
 149 
 150         if (walk_state->deferred_node) {
 151                 node = walk_state->deferred_node;
 152                 status = AE_OK;
 153         } else {
 154                 /* Execute flag should always be set when this function is entered */
 155 
 156                 if (!(walk_state->parse_flags & ACPI_PARSE_EXECUTE)) {
 157                         ACPI_ERROR((AE_INFO, "Parse execute mode is not set"));
 158                         return_ACPI_STATUS(AE_AML_INTERNAL);
 159                 }
 160 
 161                 /* Creating new namespace node, should not already exist */
 162 
 163                 flags = ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE |
 164                     ACPI_NS_ERROR_IF_FOUND;
 165 
 166                 /*
 167                  * Mark node temporary if we are executing a normal control
 168                  * method. (Don't mark if this is a module-level code method)
 169                  */
 170                 if (walk_state->method_node &&
 171                     !(walk_state->parse_flags & ACPI_PARSE_MODULE_LEVEL)) {
 172                         flags |= ACPI_NS_TEMPORARY;
 173                 }
 174 
 175                 /* Enter the name_string into the namespace */
 176 
 177                 status = acpi_ns_lookup(walk_state->scope_info,
 178                                         arg->common.value.string, ACPI_TYPE_ANY,
 179                                         ACPI_IMODE_LOAD_PASS1, flags,
 180                                         walk_state, &node);
 181                 if (ACPI_FAILURE(status)) {
 182                         ACPI_ERROR_NAMESPACE(walk_state->scope_info,
 183                                              arg->common.value.string, status);
 184                         return_ACPI_STATUS(status);
 185                 }
 186         }
 187 
 188         /*
 189          * We could put the returned object (Node) on the object stack for later,
 190          * but for now, we will put it in the "op" object that the parser uses,
 191          * so we can get it again at the end of this scope.
 192          */
 193         op->common.node = node;
 194 
 195         /*
 196          * If there is no object attached to the node, this node was just created
 197          * and we need to create the field object. Otherwise, this was a lookup
 198          * of an existing node and we don't want to create the field object again.
 199          */
 200         obj_desc = acpi_ns_get_attached_object(node);
 201         if (obj_desc) {
 202                 return_ACPI_STATUS(AE_OK);
 203         }
 204 
 205         /*
 206          * The Field definition is not fully parsed at this time.
 207          * (We must save the address of the AML for the buffer and index operands)
 208          */
 209 
 210         /* Create the buffer field object */
 211 
 212         obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_BUFFER_FIELD);
 213         if (!obj_desc) {
 214                 status = AE_NO_MEMORY;
 215                 goto cleanup;
 216         }
 217 
 218         /*
 219          * Remember location in AML stream of the field unit opcode and operands
 220          * -- since the buffer and index operands must be evaluated.
 221          */
 222         second_desc = obj_desc->common.next_object;
 223         second_desc->extra.aml_start = op->named.data;
 224         second_desc->extra.aml_length = op->named.length;
 225         obj_desc->buffer_field.node = node;
 226 
 227         /* Attach constructed field descriptors to parent node */
 228 
 229         status = acpi_ns_attach_object(node, obj_desc, ACPI_TYPE_BUFFER_FIELD);
 230         if (ACPI_FAILURE(status)) {
 231                 goto cleanup;
 232         }
 233 
 234 cleanup:
 235 
 236         /* Remove local reference to the object */
 237 
 238         acpi_ut_remove_reference(obj_desc);
 239         return_ACPI_STATUS(status);
 240 }
 241 
 242 /*******************************************************************************
 243  *
 244  * FUNCTION:    acpi_ds_get_field_names
 245  *
 246  * PARAMETERS:  info            - create_field info structure
 247  *              walk_state      - Current method state
 248  *              arg             - First parser arg for the field name list
 249  *
 250  * RETURN:      Status
 251  *
 252  * DESCRIPTION: Process all named fields in a field declaration. Names are
 253  *              entered into the namespace.
 254  *
 255  ******************************************************************************/
 256 
 257 static acpi_status
 258 acpi_ds_get_field_names(struct acpi_create_field_info *info,
 259                         struct acpi_walk_state *walk_state,
 260                         union acpi_parse_object *arg)
 261 {
 262         acpi_status status;
 263         u64 position;
 264         union acpi_parse_object *child;
 265 
 266 #ifdef ACPI_EXEC_APP
 267         u64 value = 0;
 268         union acpi_operand_object *result_desc;
 269         union acpi_operand_object *obj_desc;
 270         char *name_path;
 271 #endif
 272 
 273         ACPI_FUNCTION_TRACE_PTR(ds_get_field_names, info);
 274 
 275         /* First field starts at bit zero */
 276 
 277         info->field_bit_position = 0;
 278 
 279         /* Process all elements in the field list (of parse nodes) */
 280 
 281         while (arg) {
 282                 /*
 283                  * Four types of field elements are handled:
 284                  * 1) name - Enters a new named field into the namespace
 285                  * 2) offset - specifies a bit offset
 286                  * 3) access_as - changes the access mode/attributes
 287                  * 4) connection - Associate a resource template with the field
 288                  */
 289                 switch (arg->common.aml_opcode) {
 290                 case AML_INT_RESERVEDFIELD_OP:
 291 
 292                         position = (u64)info->field_bit_position +
 293                             (u64)arg->common.value.size;
 294 
 295                         if (position > ACPI_UINT32_MAX) {
 296                                 ACPI_ERROR((AE_INFO,
 297                                             "Bit offset within field too large (> 0xFFFFFFFF)"));
 298                                 return_ACPI_STATUS(AE_SUPPORT);
 299                         }
 300 
 301                         info->field_bit_position = (u32) position;
 302                         break;
 303 
 304                 case AML_INT_ACCESSFIELD_OP:
 305                 case AML_INT_EXTACCESSFIELD_OP:
 306                         /*
 307                          * Get new access_type, access_attribute, and access_length fields
 308                          * -- to be used for all field units that follow, until the
 309                          * end-of-field or another access_as keyword is encountered.
 310                          * NOTE. These three bytes are encoded in the integer value
 311                          * of the parseop for convenience.
 312                          *
 313                          * In field_flags, preserve the flag bits other than the
 314                          * ACCESS_TYPE bits.
 315                          */
 316 
 317                         /* access_type (byte_acc, word_acc, etc.) */
 318 
 319                         info->field_flags = (u8)
 320                             ((info->
 321                               field_flags & ~(AML_FIELD_ACCESS_TYPE_MASK)) |
 322                              ((u8)((u32)(arg->common.value.integer & 0x07))));
 323 
 324                         /* access_attribute (attrib_quick, attrib_byte, etc.) */
 325 
 326                         info->attribute = (u8)
 327                             ((arg->common.value.integer >> 8) & 0xFF);
 328 
 329                         /* access_length (for serial/buffer protocols) */
 330 
 331                         info->access_length = (u8)
 332                             ((arg->common.value.integer >> 16) & 0xFF);
 333                         break;
 334 
 335                 case AML_INT_CONNECTION_OP:
 336                         /*
 337                          * Clear any previous connection. New connection is used for all
 338                          * fields that follow, similar to access_as
 339                          */
 340                         info->resource_buffer = NULL;
 341                         info->connection_node = NULL;
 342                         info->pin_number_index = 0;
 343 
 344                         /*
 345                          * A Connection() is either an actual resource descriptor (buffer)
 346                          * or a named reference to a resource template
 347                          */
 348                         child = arg->common.value.arg;
 349                         if (child->common.aml_opcode == AML_INT_BYTELIST_OP) {
 350                                 info->resource_buffer = child->named.data;
 351                                 info->resource_length =
 352                                     (u16)child->named.value.integer;
 353                         } else {
 354                                 /* Lookup the Connection() namepath, it should already exist */
 355 
 356                                 status = acpi_ns_lookup(walk_state->scope_info,
 357                                                         child->common.value.
 358                                                         name, ACPI_TYPE_ANY,
 359                                                         ACPI_IMODE_EXECUTE,
 360                                                         ACPI_NS_DONT_OPEN_SCOPE,
 361                                                         walk_state,
 362                                                         &info->connection_node);
 363                                 if (ACPI_FAILURE(status)) {
 364                                         ACPI_ERROR_NAMESPACE(walk_state->
 365                                                              scope_info,
 366                                                              child->common.
 367                                                              value.name,
 368                                                              status);
 369                                         return_ACPI_STATUS(status);
 370                                 }
 371                         }
 372                         break;
 373 
 374                 case AML_INT_NAMEDFIELD_OP:
 375 
 376                         /* Lookup the name, it should already exist */
 377 
 378                         status = acpi_ns_lookup(walk_state->scope_info,
 379                                                 (char *)&arg->named.name,
 380                                                 info->field_type,
 381                                                 ACPI_IMODE_EXECUTE,
 382                                                 ACPI_NS_DONT_OPEN_SCOPE,
 383                                                 walk_state, &info->field_node);
 384                         if (ACPI_FAILURE(status)) {
 385                                 ACPI_ERROR_NAMESPACE(walk_state->scope_info,
 386                                                      (char *)&arg->named.name,
 387                                                      status);
 388                                 return_ACPI_STATUS(status);
 389                         } else {
 390                                 arg->common.node = info->field_node;
 391                                 info->field_bit_length = arg->common.value.size;
 392 
 393                                 /*
 394                                  * If there is no object attached to the node, this node was
 395                                  * just created and we need to create the field object.
 396                                  * Otherwise, this was a lookup of an existing node and we
 397                                  * don't want to create the field object again.
 398                                  */
 399                                 if (!acpi_ns_get_attached_object
 400                                     (info->field_node)) {
 401                                         status = acpi_ex_prep_field_value(info);
 402                                         if (ACPI_FAILURE(status)) {
 403                                                 return_ACPI_STATUS(status);
 404                                         }
 405 #ifdef ACPI_EXEC_APP
 406                                         name_path =
 407                                             acpi_ns_get_external_pathname(info->
 408                                                                           field_node);
 409                                         obj_desc =
 410                                             acpi_ut_create_integer_object
 411                                             (value);
 412                                         if (ACPI_SUCCESS
 413                                             (ae_lookup_init_file_entry
 414                                              (name_path, &value))) {
 415                                                 acpi_ex_write_data_to_field
 416                                                     (obj_desc,
 417                                                      acpi_ns_get_attached_object
 418                                                      (info->field_node),
 419                                                      &result_desc);
 420                                         }
 421                                         acpi_ut_remove_reference(obj_desc);
 422                                         ACPI_FREE(name_path);
 423 #endif
 424                                 }
 425                         }
 426 
 427                         /* Keep track of bit position for the next field */
 428 
 429                         position = (u64)info->field_bit_position +
 430                             (u64)arg->common.value.size;
 431 
 432                         if (position > ACPI_UINT32_MAX) {
 433                                 ACPI_ERROR((AE_INFO,
 434                                             "Field [%4.4s] bit offset too large (> 0xFFFFFFFF)",
 435                                             ACPI_CAST_PTR(char,
 436                                                           &info->field_node->
 437                                                           name)));
 438                                 return_ACPI_STATUS(AE_SUPPORT);
 439                         }
 440 
 441                         info->field_bit_position += info->field_bit_length;
 442                         info->pin_number_index++;       /* Index relative to previous Connection() */
 443                         break;
 444 
 445                 default:
 446 
 447                         ACPI_ERROR((AE_INFO,
 448                                     "Invalid opcode in field list: 0x%X",
 449                                     arg->common.aml_opcode));
 450                         return_ACPI_STATUS(AE_AML_BAD_OPCODE);
 451                 }
 452 
 453                 arg = arg->common.next;
 454         }
 455 
 456         return_ACPI_STATUS(AE_OK);
 457 }
 458 
 459 /*******************************************************************************
 460  *
 461  * FUNCTION:    acpi_ds_create_field
 462  *
 463  * PARAMETERS:  op              - Op containing the Field definition and args
 464  *              region_node     - Object for the containing Operation Region
 465  *  `           walk_state      - Current method state
 466  *
 467  * RETURN:      Status
 468  *
 469  * DESCRIPTION: Create a new field in the specified operation region
 470  *
 471  ******************************************************************************/
 472 
 473 acpi_status
 474 acpi_ds_create_field(union acpi_parse_object *op,
 475                      struct acpi_namespace_node *region_node,
 476                      struct acpi_walk_state *walk_state)
 477 {
 478         acpi_status status;
 479         union acpi_parse_object *arg;
 480         struct acpi_create_field_info info;
 481 
 482         ACPI_FUNCTION_TRACE_PTR(ds_create_field, op);
 483 
 484         /* First arg is the name of the parent op_region (must already exist) */
 485 
 486         arg = op->common.value.arg;
 487 
 488         if (!region_node) {
 489                 status =
 490                     acpi_ns_lookup(walk_state->scope_info,
 491                                    arg->common.value.name, ACPI_TYPE_REGION,
 492                                    ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT,
 493                                    walk_state, &region_node);
 494 #ifdef ACPI_ASL_COMPILER
 495                 status = acpi_ds_create_external_region(status, arg,
 496                                                         arg->common.value.name,
 497                                                         walk_state,
 498                                                         &region_node);
 499 #endif
 500                 if (ACPI_FAILURE(status)) {
 501                         ACPI_ERROR_NAMESPACE(walk_state->scope_info,
 502                                              arg->common.value.name, status);
 503                         return_ACPI_STATUS(status);
 504                 }
 505         }
 506 
 507         memset(&info, 0, sizeof(struct acpi_create_field_info));
 508 
 509         /* Second arg is the field flags */
 510 
 511         arg = arg->common.next;
 512         info.field_flags = (u8) arg->common.value.integer;
 513         info.attribute = 0;
 514 
 515         /* Each remaining arg is a Named Field */
 516 
 517         info.field_type = ACPI_TYPE_LOCAL_REGION_FIELD;
 518         info.region_node = region_node;
 519 
 520         status = acpi_ds_get_field_names(&info, walk_state, arg->common.next);
 521         if (info.region_node->object->region.space_id ==
 522             ACPI_ADR_SPACE_PLATFORM_COMM
 523             && !(region_node->object->field.internal_pcc_buffer =
 524                  ACPI_ALLOCATE_ZEROED(info.region_node->object->region.
 525                                       length))) {
 526                 return_ACPI_STATUS(AE_NO_MEMORY);
 527         }
 528         return_ACPI_STATUS(status);
 529 }
 530 
 531 /*******************************************************************************
 532  *
 533  * FUNCTION:    acpi_ds_init_field_objects
 534  *
 535  * PARAMETERS:  op              - Op containing the Field definition and args
 536  *  `           walk_state      - Current method state
 537  *
 538  * RETURN:      Status
 539  *
 540  * DESCRIPTION: For each "Field Unit" name in the argument list that is
 541  *              part of the field declaration, enter the name into the
 542  *              namespace.
 543  *
 544  ******************************************************************************/
 545 
 546 acpi_status
 547 acpi_ds_init_field_objects(union acpi_parse_object *op,
 548                            struct acpi_walk_state *walk_state)
 549 {
 550         acpi_status status;
 551         union acpi_parse_object *arg = NULL;
 552         struct acpi_namespace_node *node;
 553         u8 type = 0;
 554         u32 flags;
 555 
 556         ACPI_FUNCTION_TRACE_PTR(ds_init_field_objects, op);
 557 
 558         /* Execute flag should always be set when this function is entered */
 559 
 560         if (!(walk_state->parse_flags & ACPI_PARSE_EXECUTE)) {
 561                 if (walk_state->parse_flags & ACPI_PARSE_DEFERRED_OP) {
 562 
 563                         /* bank_field Op is deferred, just return OK */
 564 
 565                         return_ACPI_STATUS(AE_OK);
 566                 }
 567 
 568                 ACPI_ERROR((AE_INFO, "Parse deferred mode is not set"));
 569                 return_ACPI_STATUS(AE_AML_INTERNAL);
 570         }
 571 
 572         /*
 573          * Get the field_list argument for this opcode. This is the start of the
 574          * list of field elements.
 575          */
 576         switch (walk_state->opcode) {
 577         case AML_FIELD_OP:
 578 
 579                 arg = acpi_ps_get_arg(op, 2);
 580                 type = ACPI_TYPE_LOCAL_REGION_FIELD;
 581                 break;
 582 
 583         case AML_BANK_FIELD_OP:
 584 
 585                 arg = acpi_ps_get_arg(op, 4);
 586                 type = ACPI_TYPE_LOCAL_BANK_FIELD;
 587                 break;
 588 
 589         case AML_INDEX_FIELD_OP:
 590 
 591                 arg = acpi_ps_get_arg(op, 3);
 592                 type = ACPI_TYPE_LOCAL_INDEX_FIELD;
 593                 break;
 594 
 595         default:
 596 
 597                 return_ACPI_STATUS(AE_BAD_PARAMETER);
 598         }
 599 
 600         /* Creating new namespace node(s), should not already exist */
 601 
 602         flags = ACPI_NS_NO_UPSEARCH | ACPI_NS_DONT_OPEN_SCOPE |
 603             ACPI_NS_ERROR_IF_FOUND;
 604 
 605         /*
 606          * Mark node(s) temporary if we are executing a normal control
 607          * method. (Don't mark if this is a module-level code method)
 608          */
 609         if (walk_state->method_node &&
 610             !(walk_state->parse_flags & ACPI_PARSE_MODULE_LEVEL)) {
 611                 flags |= ACPI_NS_TEMPORARY;
 612         }
 613 #ifdef ACPI_EXEC_APP
 614         flags |= ACPI_NS_OVERRIDE_IF_FOUND;
 615 #endif
 616         /*
 617          * Walk the list of entries in the field_list
 618          * Note: field_list can be of zero length. In this case, Arg will be NULL.
 619          */
 620         while (arg) {
 621                 /*
 622                  * Ignore OFFSET/ACCESSAS/CONNECTION terms here; we are only interested
 623                  * in the field names in order to enter them into the namespace.
 624                  */
 625                 if (arg->common.aml_opcode == AML_INT_NAMEDFIELD_OP) {
 626                         status = acpi_ns_lookup(walk_state->scope_info,
 627                                                 (char *)&arg->named.name, type,
 628                                                 ACPI_IMODE_LOAD_PASS1, flags,
 629                                                 walk_state, &node);
 630                         if (ACPI_FAILURE(status)) {
 631                                 ACPI_ERROR_NAMESPACE(walk_state->scope_info,
 632                                                      (char *)&arg->named.name,
 633                                                      status);
 634                                 if (status != AE_ALREADY_EXISTS) {
 635                                         return_ACPI_STATUS(status);
 636                                 }
 637 
 638                                 /* Name already exists, just ignore this error */
 639 
 640                                 status = AE_OK;
 641                         }
 642 
 643                         arg->common.node = node;
 644                 }
 645 
 646                 /* Get the next field element in the list */
 647 
 648                 arg = arg->common.next;
 649         }
 650 
 651         return_ACPI_STATUS(AE_OK);
 652 }
 653 
 654 /*******************************************************************************
 655  *
 656  * FUNCTION:    acpi_ds_create_bank_field
 657  *
 658  * PARAMETERS:  op              - Op containing the Field definition and args
 659  *              region_node     - Object for the containing Operation Region
 660  *              walk_state      - Current method state
 661  *
 662  * RETURN:      Status
 663  *
 664  * DESCRIPTION: Create a new bank field in the specified operation region
 665  *
 666  ******************************************************************************/
 667 
 668 acpi_status
 669 acpi_ds_create_bank_field(union acpi_parse_object *op,
 670                           struct acpi_namespace_node *region_node,
 671                           struct acpi_walk_state *walk_state)
 672 {
 673         acpi_status status;
 674         union acpi_parse_object *arg;
 675         struct acpi_create_field_info info;
 676 
 677         ACPI_FUNCTION_TRACE_PTR(ds_create_bank_field, op);
 678 
 679         /* First arg is the name of the parent op_region (must already exist) */
 680 
 681         arg = op->common.value.arg;
 682         if (!region_node) {
 683                 status =
 684                     acpi_ns_lookup(walk_state->scope_info,
 685                                    arg->common.value.name, ACPI_TYPE_REGION,
 686                                    ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT,
 687                                    walk_state, &region_node);
 688 #ifdef ACPI_ASL_COMPILER
 689                 status = acpi_ds_create_external_region(status, arg,
 690                                                         arg->common.value.name,
 691                                                         walk_state,
 692                                                         &region_node);
 693 #endif
 694                 if (ACPI_FAILURE(status)) {
 695                         ACPI_ERROR_NAMESPACE(walk_state->scope_info,
 696                                              arg->common.value.name, status);
 697                         return_ACPI_STATUS(status);
 698                 }
 699         }
 700 
 701         /* Second arg is the Bank Register (Field) (must already exist) */
 702 
 703         arg = arg->common.next;
 704         status =
 705             acpi_ns_lookup(walk_state->scope_info, arg->common.value.string,
 706                            ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
 707                            ACPI_NS_SEARCH_PARENT, walk_state,
 708                            &info.register_node);
 709         if (ACPI_FAILURE(status)) {
 710                 ACPI_ERROR_NAMESPACE(walk_state->scope_info,
 711                                      arg->common.value.string, status);
 712                 return_ACPI_STATUS(status);
 713         }
 714 
 715         /*
 716          * Third arg is the bank_value
 717          * This arg is a term_arg, not a constant
 718          * It will be evaluated later, by acpi_ds_eval_bank_field_operands
 719          */
 720         arg = arg->common.next;
 721 
 722         /* Fourth arg is the field flags */
 723 
 724         arg = arg->common.next;
 725         info.field_flags = (u8) arg->common.value.integer;
 726 
 727         /* Each remaining arg is a Named Field */
 728 
 729         info.field_type = ACPI_TYPE_LOCAL_BANK_FIELD;
 730         info.region_node = region_node;
 731 
 732         /*
 733          * Use Info.data_register_node to store bank_field Op
 734          * It's safe because data_register_node will never be used when create
 735          * bank field \we store aml_start and aml_length in the bank_field Op for
 736          * late evaluation. Used in acpi_ex_prep_field_value(Info)
 737          *
 738          * TBD: Or, should we add a field in struct acpi_create_field_info, like
 739          * "void *ParentOp"?
 740          */
 741         info.data_register_node = (struct acpi_namespace_node *)op;
 742 
 743         status = acpi_ds_get_field_names(&info, walk_state, arg->common.next);
 744         return_ACPI_STATUS(status);
 745 }
 746 
 747 /*******************************************************************************
 748  *
 749  * FUNCTION:    acpi_ds_create_index_field
 750  *
 751  * PARAMETERS:  op              - Op containing the Field definition and args
 752  *              region_node     - Object for the containing Operation Region
 753  *  `           walk_state      - Current method state
 754  *
 755  * RETURN:      Status
 756  *
 757  * DESCRIPTION: Create a new index field in the specified operation region
 758  *
 759  ******************************************************************************/
 760 
 761 acpi_status
 762 acpi_ds_create_index_field(union acpi_parse_object *op,
 763                            struct acpi_namespace_node *region_node,
 764                            struct acpi_walk_state *walk_state)
 765 {
 766         acpi_status status;
 767         union acpi_parse_object *arg;
 768         struct acpi_create_field_info info;
 769 
 770         ACPI_FUNCTION_TRACE_PTR(ds_create_index_field, op);
 771 
 772         /* First arg is the name of the Index register (must already exist) */
 773 
 774         arg = op->common.value.arg;
 775         status =
 776             acpi_ns_lookup(walk_state->scope_info, arg->common.value.string,
 777                            ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
 778                            ACPI_NS_SEARCH_PARENT, walk_state,
 779                            &info.register_node);
 780         if (ACPI_FAILURE(status)) {
 781                 ACPI_ERROR_NAMESPACE(walk_state->scope_info,
 782                                      arg->common.value.string, status);
 783                 return_ACPI_STATUS(status);
 784         }
 785 
 786         /* Second arg is the data register (must already exist) */
 787 
 788         arg = arg->common.next;
 789         status =
 790             acpi_ns_lookup(walk_state->scope_info, arg->common.value.string,
 791                            ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE,
 792                            ACPI_NS_SEARCH_PARENT, walk_state,
 793                            &info.data_register_node);
 794         if (ACPI_FAILURE(status)) {
 795                 ACPI_ERROR_NAMESPACE(walk_state->scope_info,
 796                                      arg->common.value.string, status);
 797                 return_ACPI_STATUS(status);
 798         }
 799 
 800         /* Next arg is the field flags */
 801 
 802         arg = arg->common.next;
 803         info.field_flags = (u8) arg->common.value.integer;
 804 
 805         /* Each remaining arg is a Named Field */
 806 
 807         info.field_type = ACPI_TYPE_LOCAL_INDEX_FIELD;
 808         info.region_node = region_node;
 809 
 810         status = acpi_ds_get_field_names(&info, walk_state, arg->common.next);
 811         return_ACPI_STATUS(status);
 812 }

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