linux/drivers/acpi/acpica/dswload2.c
<<
>>
Prefs
   1// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
   2/******************************************************************************
   3 *
   4 * Module Name: dswload2 - Dispatcher second pass namespace load callbacks
   5 *
   6 * Copyright (C) 2000 - 2018, 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
  19#define _COMPONENT          ACPI_DISPATCHER
  20ACPI_MODULE_NAME("dswload2")
  21
  22/*******************************************************************************
  23 *
  24 * FUNCTION:    acpi_ds_load2_begin_op
  25 *
  26 * PARAMETERS:  walk_state      - Current state of the parse tree walk
  27 *              out_op          - Wher to return op if a new one is created
  28 *
  29 * RETURN:      Status
  30 *
  31 * DESCRIPTION: Descending callback used during the loading of ACPI tables.
  32 *
  33 ******************************************************************************/
  34acpi_status
  35acpi_ds_load2_begin_op(struct acpi_walk_state *walk_state,
  36                       union acpi_parse_object **out_op)
  37{
  38        union acpi_parse_object *op;
  39        struct acpi_namespace_node *node;
  40        acpi_status status;
  41        acpi_object_type object_type;
  42        char *buffer_ptr;
  43        u32 flags;
  44
  45        ACPI_FUNCTION_TRACE(ds_load2_begin_op);
  46
  47        op = walk_state->op;
  48        ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "Op=%p State=%p\n", op,
  49                          walk_state));
  50
  51        if (op) {
  52                if ((walk_state->control_state) &&
  53                    (walk_state->control_state->common.state ==
  54                     ACPI_CONTROL_CONDITIONAL_EXECUTING)) {
  55
  56                        /* We are executing a while loop outside of a method */
  57
  58                        status = acpi_ds_exec_begin_op(walk_state, out_op);
  59                        return_ACPI_STATUS(status);
  60                }
  61
  62                /* We only care about Namespace opcodes here */
  63
  64                if ((!(walk_state->op_info->flags & AML_NSOPCODE) &&
  65                     (walk_state->opcode != AML_INT_NAMEPATH_OP)) ||
  66                    (!(walk_state->op_info->flags & AML_NAMED))) {
  67                        return_ACPI_STATUS(AE_OK);
  68                }
  69
  70                /* Get the name we are going to enter or lookup in the namespace */
  71
  72                if (walk_state->opcode == AML_INT_NAMEPATH_OP) {
  73
  74                        /* For Namepath op, get the path string */
  75
  76                        buffer_ptr = op->common.value.string;
  77                        if (!buffer_ptr) {
  78
  79                                /* No name, just exit */
  80
  81                                return_ACPI_STATUS(AE_OK);
  82                        }
  83                } else {
  84                        /* Get name from the op */
  85
  86                        buffer_ptr = ACPI_CAST_PTR(char, &op->named.name);
  87                }
  88        } else {
  89                /* Get the namestring from the raw AML */
  90
  91                buffer_ptr =
  92                    acpi_ps_get_next_namestring(&walk_state->parser_state);
  93        }
  94
  95        /* Map the opcode into an internal object type */
  96
  97        object_type = walk_state->op_info->object_type;
  98
  99        ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
 100                          "State=%p Op=%p Type=%X\n", walk_state, op,
 101                          object_type));
 102
 103        switch (walk_state->opcode) {
 104        case AML_FIELD_OP:
 105        case AML_BANK_FIELD_OP:
 106        case AML_INDEX_FIELD_OP:
 107
 108                node = NULL;
 109                status = AE_OK;
 110                break;
 111
 112        case AML_INT_NAMEPATH_OP:
 113                /*
 114                 * The name_path is an object reference to an existing object.
 115                 * Don't enter the name into the namespace, but look it up
 116                 * for use later.
 117                 */
 118                status =
 119                    acpi_ns_lookup(walk_state->scope_info, buffer_ptr,
 120                                   object_type, ACPI_IMODE_EXECUTE,
 121                                   ACPI_NS_SEARCH_PARENT, walk_state, &(node));
 122                break;
 123
 124        case AML_SCOPE_OP:
 125
 126                /* Special case for Scope(\) -> refers to the Root node */
 127
 128                if (op && (op->named.node == acpi_gbl_root_node)) {
 129                        node = op->named.node;
 130
 131                        status =
 132                            acpi_ds_scope_stack_push(node, object_type,
 133                                                     walk_state);
 134                        if (ACPI_FAILURE(status)) {
 135                                return_ACPI_STATUS(status);
 136                        }
 137                } else {
 138                        /*
 139                         * The Path is an object reference to an existing object.
 140                         * Don't enter the name into the namespace, but look it up
 141                         * for use later.
 142                         */
 143                        status =
 144                            acpi_ns_lookup(walk_state->scope_info, buffer_ptr,
 145                                           object_type, ACPI_IMODE_EXECUTE,
 146                                           ACPI_NS_SEARCH_PARENT, walk_state,
 147                                           &(node));
 148                        if (ACPI_FAILURE(status)) {
 149#ifdef ACPI_ASL_COMPILER
 150                                if (status == AE_NOT_FOUND) {
 151                                        status = AE_OK;
 152                                } else {
 153                                        ACPI_ERROR_NAMESPACE(walk_state->
 154                                                             scope_info,
 155                                                             buffer_ptr,
 156                                                             status);
 157                                }
 158#else
 159                                ACPI_ERROR_NAMESPACE(walk_state->scope_info,
 160                                                     buffer_ptr, status);
 161#endif
 162                                return_ACPI_STATUS(status);
 163                        }
 164                }
 165
 166                /*
 167                 * We must check to make sure that the target is
 168                 * one of the opcodes that actually opens a scope
 169                 */
 170                switch (node->type) {
 171                case ACPI_TYPE_ANY:
 172                case ACPI_TYPE_LOCAL_SCOPE:     /* Scope */
 173                case ACPI_TYPE_DEVICE:
 174                case ACPI_TYPE_POWER:
 175                case ACPI_TYPE_PROCESSOR:
 176                case ACPI_TYPE_THERMAL:
 177
 178                        /* These are acceptable types */
 179                        break;
 180
 181                case ACPI_TYPE_INTEGER:
 182                case ACPI_TYPE_STRING:
 183                case ACPI_TYPE_BUFFER:
 184
 185                        /*
 186                         * These types we will allow, but we will change the type.
 187                         * This enables some existing code of the form:
 188                         *
 189                         *  Name (DEB, 0)
 190                         *  Scope (DEB) { ... }
 191                         */
 192                        ACPI_WARNING((AE_INFO,
 193                                      "Type override - [%4.4s] had invalid type (%s) "
 194                                      "for Scope operator, changed to type ANY",
 195                                      acpi_ut_get_node_name(node),
 196                                      acpi_ut_get_type_name(node->type)));
 197
 198                        node->type = ACPI_TYPE_ANY;
 199                        walk_state->scope_info->common.value = ACPI_TYPE_ANY;
 200                        break;
 201
 202                case ACPI_TYPE_METHOD:
 203
 204                        /*
 205                         * Allow scope change to root during execution of module-level
 206                         * code. Root is typed METHOD during this time.
 207                         */
 208                        if ((node == acpi_gbl_root_node) &&
 209                            (walk_state->
 210                             parse_flags & ACPI_PARSE_MODULE_LEVEL)) {
 211                                break;
 212                        }
 213
 214                        /*lint -fallthrough */
 215
 216                default:
 217
 218                        /* All other types are an error */
 219
 220                        ACPI_ERROR((AE_INFO,
 221                                    "Invalid type (%s) for target of "
 222                                    "Scope operator [%4.4s] (Cannot override)",
 223                                    acpi_ut_get_type_name(node->type),
 224                                    acpi_ut_get_node_name(node)));
 225
 226                        return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
 227                }
 228                break;
 229
 230        default:
 231
 232                /* All other opcodes */
 233
 234                if (op && op->common.node) {
 235
 236                        /* This op/node was previously entered into the namespace */
 237
 238                        node = op->common.node;
 239
 240                        if (acpi_ns_opens_scope(object_type)) {
 241                                status =
 242                                    acpi_ds_scope_stack_push(node, object_type,
 243                                                             walk_state);
 244                                if (ACPI_FAILURE(status)) {
 245                                        return_ACPI_STATUS(status);
 246                                }
 247                        }
 248
 249                        return_ACPI_STATUS(AE_OK);
 250                }
 251
 252                /*
 253                 * Enter the named type into the internal namespace. We enter the name
 254                 * as we go downward in the parse tree. Any necessary subobjects that
 255                 * involve arguments to the opcode must be created as we go back up the
 256                 * parse tree later.
 257                 *
 258                 * Note: Name may already exist if we are executing a deferred opcode.
 259                 */
 260                if (walk_state->deferred_node) {
 261
 262                        /* This name is already in the namespace, get the node */
 263
 264                        node = walk_state->deferred_node;
 265                        status = AE_OK;
 266                        break;
 267                }
 268
 269                flags = ACPI_NS_NO_UPSEARCH;
 270                if (walk_state->pass_number == ACPI_IMODE_EXECUTE) {
 271
 272                        /* Execution mode, node cannot already exist, node is temporary */
 273
 274                        flags |= ACPI_NS_ERROR_IF_FOUND;
 275
 276                        if (!
 277                            (walk_state->
 278                             parse_flags & ACPI_PARSE_MODULE_LEVEL)) {
 279                                flags |= ACPI_NS_TEMPORARY;
 280                        }
 281                }
 282#ifdef ACPI_ASL_COMPILER
 283
 284                /*
 285                 * Do not open a scope for AML_EXTERNAL_OP
 286                 * acpi_ns_lookup can open a new scope based on the object type
 287                 * of this op. AML_EXTERNAL_OP is a declaration rather than a
 288                 * definition. In the case that this external is a method object,
 289                 * acpi_ns_lookup will open a new scope. However, an AML_EXTERNAL_OP
 290                 * associated with the ACPI_TYPE_METHOD is a declaration, rather than
 291                 * a definition. Flags is set to avoid opening a scope for any
 292                 * AML_EXTERNAL_OP.
 293                 */
 294                if (walk_state->opcode == AML_EXTERNAL_OP) {
 295                        flags |= ACPI_NS_DONT_OPEN_SCOPE;
 296                }
 297#endif
 298
 299                /* Add new entry or lookup existing entry */
 300
 301                status =
 302                    acpi_ns_lookup(walk_state->scope_info, buffer_ptr,
 303                                   object_type, ACPI_IMODE_LOAD_PASS2, flags,
 304                                   walk_state, &node);
 305
 306                if (ACPI_SUCCESS(status) && (flags & ACPI_NS_TEMPORARY)) {
 307                        ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
 308                                          "***New Node [%4.4s] %p is temporary\n",
 309                                          acpi_ut_get_node_name(node), node));
 310                }
 311                break;
 312        }
 313
 314        if (ACPI_FAILURE(status)) {
 315                ACPI_ERROR_NAMESPACE(walk_state->scope_info,
 316                                     buffer_ptr, status);
 317                return_ACPI_STATUS(status);
 318        }
 319
 320        if (!op) {
 321
 322                /* Create a new op */
 323
 324                op = acpi_ps_alloc_op(walk_state->opcode, walk_state->aml);
 325                if (!op) {
 326                        return_ACPI_STATUS(AE_NO_MEMORY);
 327                }
 328
 329                /* Initialize the new op */
 330
 331                if (node) {
 332                        op->named.name = node->name.integer;
 333                }
 334                *out_op = op;
 335        }
 336
 337        /*
 338         * Put the Node in the "op" object that the parser uses, so we
 339         * can get it again quickly when this scope is closed
 340         */
 341        op->common.node = node;
 342        return_ACPI_STATUS(status);
 343}
 344
 345/*******************************************************************************
 346 *
 347 * FUNCTION:    acpi_ds_load2_end_op
 348 *
 349 * PARAMETERS:  walk_state      - Current state of the parse tree walk
 350 *
 351 * RETURN:      Status
 352 *
 353 * DESCRIPTION: Ascending callback used during the loading of the namespace,
 354 *              both control methods and everything else.
 355 *
 356 ******************************************************************************/
 357
 358acpi_status acpi_ds_load2_end_op(struct acpi_walk_state *walk_state)
 359{
 360        union acpi_parse_object *op;
 361        acpi_status status = AE_OK;
 362        acpi_object_type object_type;
 363        struct acpi_namespace_node *node;
 364        union acpi_parse_object *arg;
 365        struct acpi_namespace_node *new_node;
 366#ifndef ACPI_NO_METHOD_EXECUTION
 367        u32 i;
 368        u8 region_space;
 369#endif
 370
 371        ACPI_FUNCTION_TRACE(ds_load2_end_op);
 372
 373        op = walk_state->op;
 374        ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "Opcode [%s] Op %p State %p\n",
 375                          walk_state->op_info->name, op, walk_state));
 376
 377        /* Check if opcode had an associated namespace object */
 378
 379        if (!(walk_state->op_info->flags & AML_NSOBJECT)) {
 380                return_ACPI_STATUS(AE_OK);
 381        }
 382
 383        if (op->common.aml_opcode == AML_SCOPE_OP) {
 384                ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
 385                                  "Ending scope Op=%p State=%p\n", op,
 386                                  walk_state));
 387        }
 388
 389        object_type = walk_state->op_info->object_type;
 390
 391        /*
 392         * Get the Node/name from the earlier lookup
 393         * (It was saved in the *op structure)
 394         */
 395        node = op->common.node;
 396
 397        /*
 398         * Put the Node on the object stack (Contains the ACPI Name of
 399         * this object)
 400         */
 401        walk_state->operands[0] = (void *)node;
 402        walk_state->num_operands = 1;
 403
 404        /* Pop the scope stack */
 405
 406        if (acpi_ns_opens_scope(object_type) &&
 407            (op->common.aml_opcode != AML_INT_METHODCALL_OP)) {
 408                ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
 409                                  "(%s) Popping scope for Op %p\n",
 410                                  acpi_ut_get_type_name(object_type), op));
 411
 412                status = acpi_ds_scope_stack_pop(walk_state);
 413                if (ACPI_FAILURE(status)) {
 414                        goto cleanup;
 415                }
 416        }
 417
 418        /*
 419         * Named operations are as follows:
 420         *
 421         * AML_ALIAS
 422         * AML_BANKFIELD
 423         * AML_CREATEBITFIELD
 424         * AML_CREATEBYTEFIELD
 425         * AML_CREATEDWORDFIELD
 426         * AML_CREATEFIELD
 427         * AML_CREATEQWORDFIELD
 428         * AML_CREATEWORDFIELD
 429         * AML_DATA_REGION
 430         * AML_DEVICE
 431         * AML_EVENT
 432         * AML_FIELD
 433         * AML_INDEXFIELD
 434         * AML_METHOD
 435         * AML_METHODCALL
 436         * AML_MUTEX
 437         * AML_NAME
 438         * AML_NAMEDFIELD
 439         * AML_OPREGION
 440         * AML_POWERRES
 441         * AML_PROCESSOR
 442         * AML_SCOPE
 443         * AML_THERMALZONE
 444         */
 445
 446        ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
 447                          "Create-Load [%s] State=%p Op=%p NamedObj=%p\n",
 448                          acpi_ps_get_opcode_name(op->common.aml_opcode),
 449                          walk_state, op, node));
 450
 451        /* Decode the opcode */
 452
 453        arg = op->common.value.arg;
 454
 455        switch (walk_state->op_info->type) {
 456#ifndef ACPI_NO_METHOD_EXECUTION
 457
 458        case AML_TYPE_CREATE_FIELD:
 459                /*
 460                 * Create the field object, but the field buffer and index must
 461                 * be evaluated later during the execution phase
 462                 */
 463                status = acpi_ds_create_buffer_field(op, walk_state);
 464                break;
 465
 466        case AML_TYPE_NAMED_FIELD:
 467                /*
 468                 * If we are executing a method, initialize the field
 469                 */
 470                if (walk_state->method_node) {
 471                        status = acpi_ds_init_field_objects(op, walk_state);
 472                }
 473
 474                switch (op->common.aml_opcode) {
 475                case AML_INDEX_FIELD_OP:
 476
 477                        status =
 478                            acpi_ds_create_index_field(op,
 479                                                       (acpi_handle)arg->common.
 480                                                       node, walk_state);
 481                        break;
 482
 483                case AML_BANK_FIELD_OP:
 484
 485                        status =
 486                            acpi_ds_create_bank_field(op, arg->common.node,
 487                                                      walk_state);
 488                        break;
 489
 490                case AML_FIELD_OP:
 491
 492                        status =
 493                            acpi_ds_create_field(op, arg->common.node,
 494                                                 walk_state);
 495                        break;
 496
 497                default:
 498
 499                        /* All NAMED_FIELD opcodes must be handled above */
 500                        break;
 501                }
 502                break;
 503
 504        case AML_TYPE_NAMED_SIMPLE:
 505
 506                status = acpi_ds_create_operands(walk_state, arg);
 507                if (ACPI_FAILURE(status)) {
 508                        goto cleanup;
 509                }
 510
 511                switch (op->common.aml_opcode) {
 512                case AML_PROCESSOR_OP:
 513
 514                        status = acpi_ex_create_processor(walk_state);
 515                        break;
 516
 517                case AML_POWER_RESOURCE_OP:
 518
 519                        status = acpi_ex_create_power_resource(walk_state);
 520                        break;
 521
 522                case AML_MUTEX_OP:
 523
 524                        status = acpi_ex_create_mutex(walk_state);
 525                        break;
 526
 527                case AML_EVENT_OP:
 528
 529                        status = acpi_ex_create_event(walk_state);
 530                        break;
 531
 532                case AML_ALIAS_OP:
 533
 534                        status = acpi_ex_create_alias(walk_state);
 535                        break;
 536
 537                default:
 538
 539                        /* Unknown opcode */
 540
 541                        status = AE_OK;
 542                        goto cleanup;
 543                }
 544
 545                /* Delete operands */
 546
 547                for (i = 1; i < walk_state->num_operands; i++) {
 548                        acpi_ut_remove_reference(walk_state->operands[i]);
 549                        walk_state->operands[i] = NULL;
 550                }
 551
 552                break;
 553#endif                          /* ACPI_NO_METHOD_EXECUTION */
 554
 555        case AML_TYPE_NAMED_COMPLEX:
 556
 557                switch (op->common.aml_opcode) {
 558#ifndef ACPI_NO_METHOD_EXECUTION
 559                case AML_REGION_OP:
 560                case AML_DATA_REGION_OP:
 561
 562                        if (op->common.aml_opcode == AML_REGION_OP) {
 563                                region_space = (acpi_adr_space_type)
 564                                    ((op->common.value.arg)->common.value.
 565                                     integer);
 566                        } else {
 567                                region_space = ACPI_ADR_SPACE_DATA_TABLE;
 568                        }
 569
 570                        /*
 571                         * The op_region is not fully parsed at this time. The only valid
 572                         * argument is the space_id. (We must save the address of the
 573                         * AML of the address and length operands)
 574                         *
 575                         * If we have a valid region, initialize it. The namespace is
 576                         * unlocked at this point.
 577                         *
 578                         * Need to unlock interpreter if it is locked (if we are running
 579                         * a control method), in order to allow _REG methods to be run
 580                         * during acpi_ev_initialize_region.
 581                         */
 582                        if (walk_state->method_node) {
 583                                /*
 584                                 * Executing a method: initialize the region and unlock
 585                                 * the interpreter
 586                                 */
 587                                status = acpi_ex_create_region(op->named.data,
 588                                                               op->named.length,
 589                                                               region_space,
 590                                                               walk_state);
 591                                if (ACPI_FAILURE(status)) {
 592                                        return_ACPI_STATUS(status);
 593                                }
 594                        }
 595
 596                        status =
 597                            acpi_ev_initialize_region
 598                            (acpi_ns_get_attached_object(node));
 599                        break;
 600
 601                case AML_NAME_OP:
 602
 603                        status = acpi_ds_create_node(walk_state, node, op);
 604                        break;
 605
 606                case AML_METHOD_OP:
 607                        /*
 608                         * method_op pkg_length name_string method_flags term_list
 609                         *
 610                         * Note: We must create the method node/object pair as soon as we
 611                         * see the method declaration. This allows later pass1 parsing
 612                         * of invocations of the method (need to know the number of
 613                         * arguments.)
 614                         */
 615                        ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
 616                                          "LOADING-Method: State=%p Op=%p NamedObj=%p\n",
 617                                          walk_state, op, op->named.node));
 618
 619                        if (!acpi_ns_get_attached_object(op->named.node)) {
 620                                walk_state->operands[0] =
 621                                    ACPI_CAST_PTR(void, op->named.node);
 622                                walk_state->num_operands = 1;
 623
 624                                status =
 625                                    acpi_ds_create_operands(walk_state,
 626                                                            op->common.value.
 627                                                            arg);
 628                                if (ACPI_SUCCESS(status)) {
 629                                        status =
 630                                            acpi_ex_create_method(op->named.
 631                                                                  data,
 632                                                                  op->named.
 633                                                                  length,
 634                                                                  walk_state);
 635                                }
 636
 637                                walk_state->operands[0] = NULL;
 638                                walk_state->num_operands = 0;
 639
 640                                if (ACPI_FAILURE(status)) {
 641                                        return_ACPI_STATUS(status);
 642                                }
 643                        }
 644                        break;
 645
 646#endif                          /* ACPI_NO_METHOD_EXECUTION */
 647
 648                default:
 649
 650                        /* All NAMED_COMPLEX opcodes must be handled above */
 651                        break;
 652                }
 653                break;
 654
 655        case AML_CLASS_INTERNAL:
 656
 657                /* case AML_INT_NAMEPATH_OP: */
 658                break;
 659
 660        case AML_CLASS_METHOD_CALL:
 661
 662                ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
 663                                  "RESOLVING-MethodCall: State=%p Op=%p NamedObj=%p\n",
 664                                  walk_state, op, node));
 665
 666                /*
 667                 * Lookup the method name and save the Node
 668                 */
 669                status =
 670                    acpi_ns_lookup(walk_state->scope_info,
 671                                   arg->common.value.string, ACPI_TYPE_ANY,
 672                                   ACPI_IMODE_LOAD_PASS2,
 673                                   ACPI_NS_SEARCH_PARENT |
 674                                   ACPI_NS_DONT_OPEN_SCOPE, walk_state,
 675                                   &(new_node));
 676                if (ACPI_SUCCESS(status)) {
 677                        /*
 678                         * Make sure that what we found is indeed a method
 679                         * We didn't search for a method on purpose, to see if the name
 680                         * would resolve
 681                         */
 682                        if (new_node->type != ACPI_TYPE_METHOD) {
 683                                status = AE_AML_OPERAND_TYPE;
 684                        }
 685
 686                        /* We could put the returned object (Node) on the object stack for
 687                         * later, but for now, we will put it in the "op" object that the
 688                         * parser uses, so we can get it again at the end of this scope
 689                         */
 690                        op->common.node = new_node;
 691                } else {
 692                        ACPI_ERROR_NAMESPACE(walk_state->scope_info,
 693                                             arg->common.value.string, status);
 694                }
 695                break;
 696
 697        default:
 698
 699                break;
 700        }
 701
 702cleanup:
 703
 704        /* Remove the Node pushed at the very beginning */
 705
 706        walk_state->operands[0] = NULL;
 707        walk_state->num_operands = 0;
 708        return_ACPI_STATUS(status);
 709}
 710