root/drivers/acpi/acpica/dswload.c

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

DEFINITIONS

This source file includes following definitions.
  1. ACPI_MODULE_NAME
  2. acpi_ds_load1_begin_op
  3. acpi_ds_load1_end_op

   1 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
   2 /******************************************************************************
   3  *
   4  * Module Name: dswload - Dispatcher first pass namespace load callbacks
   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 #ifdef ACPI_ASL_COMPILER
  18 #include "acdisasm.h"
  19 #endif
  20 
  21 #define _COMPONENT          ACPI_DISPATCHER
  22 ACPI_MODULE_NAME("dswload")
  23 
  24 /*******************************************************************************
  25  *
  26  * FUNCTION:    acpi_ds_init_callbacks
  27  *
  28  * PARAMETERS:  walk_state      - Current state of the parse tree walk
  29  *              pass_number     - 1, 2, or 3
  30  *
  31  * RETURN:      Status
  32  *
  33  * DESCRIPTION: Init walk state callbacks
  34  *
  35  ******************************************************************************/
  36 acpi_status
  37 acpi_ds_init_callbacks(struct acpi_walk_state *walk_state, u32 pass_number)
  38 {
  39 
  40         switch (pass_number) {
  41         case 0:
  42 
  43                 /* Parse only - caller will setup callbacks */
  44 
  45                 walk_state->parse_flags = ACPI_PARSE_LOAD_PASS1 |
  46                     ACPI_PARSE_DELETE_TREE | ACPI_PARSE_DISASSEMBLE;
  47                 walk_state->descending_callback = NULL;
  48                 walk_state->ascending_callback = NULL;
  49                 break;
  50 
  51         case 1:
  52 
  53                 /* Load pass 1 */
  54 
  55                 walk_state->parse_flags = ACPI_PARSE_LOAD_PASS1 |
  56                     ACPI_PARSE_DELETE_TREE;
  57                 walk_state->descending_callback = acpi_ds_load1_begin_op;
  58                 walk_state->ascending_callback = acpi_ds_load1_end_op;
  59                 break;
  60 
  61         case 2:
  62 
  63                 /* Load pass 2 */
  64 
  65                 walk_state->parse_flags = ACPI_PARSE_LOAD_PASS1 |
  66                     ACPI_PARSE_DELETE_TREE;
  67                 walk_state->descending_callback = acpi_ds_load2_begin_op;
  68                 walk_state->ascending_callback = acpi_ds_load2_end_op;
  69                 break;
  70 
  71         case 3:
  72 
  73                 /* Execution pass */
  74 
  75                 walk_state->parse_flags |= ACPI_PARSE_EXECUTE |
  76                     ACPI_PARSE_DELETE_TREE;
  77                 walk_state->descending_callback = acpi_ds_exec_begin_op;
  78                 walk_state->ascending_callback = acpi_ds_exec_end_op;
  79                 break;
  80 
  81         default:
  82 
  83                 return (AE_BAD_PARAMETER);
  84         }
  85 
  86         return (AE_OK);
  87 }
  88 
  89 /*******************************************************************************
  90  *
  91  * FUNCTION:    acpi_ds_load1_begin_op
  92  *
  93  * PARAMETERS:  walk_state      - Current state of the parse tree walk
  94  *              out_op          - Where to return op if a new one is created
  95  *
  96  * RETURN:      Status
  97  *
  98  * DESCRIPTION: Descending callback used during the loading of ACPI tables.
  99  *
 100  ******************************************************************************/
 101 
 102 acpi_status
 103 acpi_ds_load1_begin_op(struct acpi_walk_state *walk_state,
 104                        union acpi_parse_object **out_op)
 105 {
 106         union acpi_parse_object *op;
 107         struct acpi_namespace_node *node;
 108         acpi_status status;
 109         acpi_object_type object_type;
 110         char *path;
 111         u32 flags;
 112 
 113         ACPI_FUNCTION_TRACE_PTR(ds_load1_begin_op, walk_state->op);
 114 
 115         op = walk_state->op;
 116         ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "Op=%p State=%p\n", op,
 117                           walk_state));
 118 
 119         /* We are only interested in opcodes that have an associated name */
 120 
 121         if (op) {
 122                 if (!(walk_state->op_info->flags & AML_NAMED)) {
 123                         *out_op = op;
 124                         return_ACPI_STATUS(AE_OK);
 125                 }
 126 
 127                 /* Check if this object has already been installed in the namespace */
 128 
 129                 if (op->common.node) {
 130                         *out_op = op;
 131                         return_ACPI_STATUS(AE_OK);
 132                 }
 133         }
 134 
 135         path = acpi_ps_get_next_namestring(&walk_state->parser_state);
 136 
 137         /* Map the raw opcode into an internal object type */
 138 
 139         object_type = walk_state->op_info->object_type;
 140 
 141         ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
 142                           "State=%p Op=%p [%s]\n", walk_state, op,
 143                           acpi_ut_get_type_name(object_type)));
 144 
 145         switch (walk_state->opcode) {
 146         case AML_SCOPE_OP:
 147                 /*
 148                  * The target name of the Scope() operator must exist at this point so
 149                  * that we can actually open the scope to enter new names underneath it.
 150                  * Allow search-to-root for single namesegs.
 151                  */
 152                 status =
 153                     acpi_ns_lookup(walk_state->scope_info, path, object_type,
 154                                    ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT,
 155                                    walk_state, &(node));
 156 #ifdef ACPI_ASL_COMPILER
 157                 if (status == AE_NOT_FOUND) {
 158                         /*
 159                          * Table disassembly:
 160                          * Target of Scope() not found. Generate an External for it, and
 161                          * insert the name into the namespace.
 162                          */
 163                         acpi_dm_add_op_to_external_list(op, path,
 164                                                         ACPI_TYPE_DEVICE, 0, 0);
 165                         status =
 166                             acpi_ns_lookup(walk_state->scope_info, path,
 167                                            object_type, ACPI_IMODE_LOAD_PASS1,
 168                                            ACPI_NS_SEARCH_PARENT, walk_state,
 169                                            &node);
 170                 }
 171 #endif
 172                 if (ACPI_FAILURE(status)) {
 173                         ACPI_ERROR_NAMESPACE(walk_state->scope_info, path,
 174                                              status);
 175                         return_ACPI_STATUS(status);
 176                 }
 177 
 178                 /*
 179                  * Check to make sure that the target is
 180                  * one of the opcodes that actually opens a scope
 181                  */
 182                 switch (node->type) {
 183                 case ACPI_TYPE_ANY:
 184                 case ACPI_TYPE_LOCAL_SCOPE:     /* Scope  */
 185                 case ACPI_TYPE_DEVICE:
 186                 case ACPI_TYPE_POWER:
 187                 case ACPI_TYPE_PROCESSOR:
 188                 case ACPI_TYPE_THERMAL:
 189 
 190                         /* These are acceptable types */
 191                         break;
 192 
 193                 case ACPI_TYPE_INTEGER:
 194                 case ACPI_TYPE_STRING:
 195                 case ACPI_TYPE_BUFFER:
 196                         /*
 197                          * These types we will allow, but we will change the type.
 198                          * This enables some existing code of the form:
 199                          *
 200                          *  Name (DEB, 0)
 201                          *  Scope (DEB) { ... }
 202                          *
 203                          * Note: silently change the type here. On the second pass,
 204                          * we will report a warning
 205                          */
 206                         ACPI_DEBUG_PRINT((ACPI_DB_INFO,
 207                                           "Type override - [%4.4s] had invalid type (%s) "
 208                                           "for Scope operator, changed to type ANY\n",
 209                                           acpi_ut_get_node_name(node),
 210                                           acpi_ut_get_type_name(node->type)));
 211 
 212                         node->type = ACPI_TYPE_ANY;
 213                         walk_state->scope_info->common.value = ACPI_TYPE_ANY;
 214                         break;
 215 
 216                 case ACPI_TYPE_METHOD:
 217                         /*
 218                          * Allow scope change to root during execution of module-level
 219                          * code. Root is typed METHOD during this time.
 220                          */
 221                         if ((node == acpi_gbl_root_node) &&
 222                             (walk_state->
 223                              parse_flags & ACPI_PARSE_MODULE_LEVEL)) {
 224                                 break;
 225                         }
 226 
 227                         /*lint -fallthrough */
 228 
 229                 default:
 230 
 231                         /* All other types are an error */
 232 
 233                         ACPI_ERROR((AE_INFO,
 234                                     "Invalid type (%s) for target of "
 235                                     "Scope operator [%4.4s] (Cannot override)",
 236                                     acpi_ut_get_type_name(node->type),
 237                                     acpi_ut_get_node_name(node)));
 238 
 239                         return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
 240                 }
 241                 break;
 242 
 243         default:
 244                 /*
 245                  * For all other named opcodes, we will enter the name into
 246                  * the namespace.
 247                  *
 248                  * Setup the search flags.
 249                  * Since we are entering a name into the namespace, we do not want to
 250                  * enable the search-to-root upsearch.
 251                  *
 252                  * There are only two conditions where it is acceptable that the name
 253                  * already exists:
 254                  *    1) the Scope() operator can reopen a scoping object that was
 255                  *       previously defined (Scope, Method, Device, etc.)
 256                  *    2) Whenever we are parsing a deferred opcode (op_region, Buffer,
 257                  *       buffer_field, or Package), the name of the object is already
 258                  *       in the namespace.
 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                 /*
 270                  * If we are executing a method, do not create any namespace objects
 271                  * during the load phase, only during execution.
 272                  */
 273                 if (walk_state->method_node) {
 274                         node = NULL;
 275                         status = AE_OK;
 276                         break;
 277                 }
 278 
 279                 flags = ACPI_NS_NO_UPSEARCH;
 280                 if ((walk_state->opcode != AML_SCOPE_OP) &&
 281                     (!(walk_state->parse_flags & ACPI_PARSE_DEFERRED_OP))) {
 282                         if (walk_state->namespace_override) {
 283                                 flags |= ACPI_NS_OVERRIDE_IF_FOUND;
 284                                 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
 285                                                   "[%s] Override allowed\n",
 286                                                   acpi_ut_get_type_name
 287                                                   (object_type)));
 288                         } else {
 289                                 flags |= ACPI_NS_ERROR_IF_FOUND;
 290                                 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
 291                                                   "[%s] Cannot already exist\n",
 292                                                   acpi_ut_get_type_name
 293                                                   (object_type)));
 294                         }
 295                 } else {
 296                         ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
 297                                           "[%s] Both Find or Create allowed\n",
 298                                           acpi_ut_get_type_name(object_type)));
 299                 }
 300 
 301                 /*
 302                  * Enter the named type into the internal namespace. We enter the name
 303                  * as we go downward in the parse tree. Any necessary subobjects that
 304                  * involve arguments to the opcode must be created as we go back up the
 305                  * parse tree later.
 306                  */
 307                 status =
 308                     acpi_ns_lookup(walk_state->scope_info, path, object_type,
 309                                    ACPI_IMODE_LOAD_PASS1, flags, walk_state,
 310                                    &node);
 311                 if (ACPI_FAILURE(status)) {
 312                         if (status == AE_ALREADY_EXISTS) {
 313 
 314                                 /* The name already exists in this scope */
 315 
 316                                 if (node->flags & ANOBJ_IS_EXTERNAL) {
 317                                         /*
 318                                          * Allow one create on an object or segment that was
 319                                          * previously declared External
 320                                          */
 321                                         node->flags &= ~ANOBJ_IS_EXTERNAL;
 322                                         node->type = (u8) object_type;
 323 
 324                                         /* Just retyped a node, probably will need to open a scope */
 325 
 326                                         if (acpi_ns_opens_scope(object_type)) {
 327                                                 status =
 328                                                     acpi_ds_scope_stack_push
 329                                                     (node, object_type,
 330                                                      walk_state);
 331                                                 if (ACPI_FAILURE(status)) {
 332                                                         return_ACPI_STATUS
 333                                                             (status);
 334                                                 }
 335                                         }
 336 
 337                                         status = AE_OK;
 338                                 }
 339                         }
 340 
 341                         if (ACPI_FAILURE(status)) {
 342                                 ACPI_ERROR_NAMESPACE(walk_state->scope_info,
 343                                                      path, status);
 344                                 return_ACPI_STATUS(status);
 345                         }
 346                 }
 347                 break;
 348         }
 349 
 350         /* Common exit */
 351 
 352         if (!op) {
 353 
 354                 /* Create a new op */
 355 
 356                 op = acpi_ps_alloc_op(walk_state->opcode, walk_state->aml);
 357                 if (!op) {
 358                         return_ACPI_STATUS(AE_NO_MEMORY);
 359                 }
 360         }
 361 
 362         /* Initialize the op */
 363 
 364 #ifdef ACPI_CONSTANT_EVAL_ONLY
 365         op->named.path = path;
 366 #endif
 367 
 368         if (node) {
 369                 /*
 370                  * Put the Node in the "op" object that the parser uses, so we
 371                  * can get it again quickly when this scope is closed
 372                  */
 373                 op->common.node = node;
 374                 op->named.name = node->name.integer;
 375         }
 376 
 377         acpi_ps_append_arg(acpi_ps_get_parent_scope(&walk_state->parser_state),
 378                            op);
 379         *out_op = op;
 380         return_ACPI_STATUS(status);
 381 }
 382 
 383 /*******************************************************************************
 384  *
 385  * FUNCTION:    acpi_ds_load1_end_op
 386  *
 387  * PARAMETERS:  walk_state      - Current state of the parse tree walk
 388  *
 389  * RETURN:      Status
 390  *
 391  * DESCRIPTION: Ascending callback used during the loading of the namespace,
 392  *              both control methods and everything else.
 393  *
 394  ******************************************************************************/
 395 
 396 acpi_status acpi_ds_load1_end_op(struct acpi_walk_state *walk_state)
 397 {
 398         union acpi_parse_object *op;
 399         acpi_object_type object_type;
 400         acpi_status status = AE_OK;
 401 #ifdef ACPI_ASL_COMPILER
 402         u8 param_count;
 403 #endif
 404 
 405         ACPI_FUNCTION_TRACE(ds_load1_end_op);
 406 
 407         op = walk_state->op;
 408         ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "Op=%p State=%p\n", op,
 409                           walk_state));
 410 
 411         /*
 412          * Disassembler: handle create field operators here.
 413          *
 414          * create_buffer_field is a deferred op that is typically processed in load
 415          * pass 2. However, disassembly of control method contents walk the parse
 416          * tree with ACPI_PARSE_LOAD_PASS1 and AML_CREATE operators are processed
 417          * in a later walk. This is a problem when there is a control method that
 418          * has the same name as the AML_CREATE object. In this case, any use of the
 419          * name segment will be detected as a method call rather than a reference
 420          * to a buffer field.
 421          *
 422          * This earlier creation during disassembly solves this issue by inserting
 423          * the named object in the ACPI namespace so that references to this name
 424          * would be a name string rather than a method call.
 425          */
 426         if ((walk_state->parse_flags & ACPI_PARSE_DISASSEMBLE) &&
 427             (walk_state->op_info->flags & AML_CREATE)) {
 428                 status = acpi_ds_create_buffer_field(op, walk_state);
 429                 return_ACPI_STATUS(status);
 430         }
 431 
 432         /* We are only interested in opcodes that have an associated name */
 433 
 434         if (!(walk_state->op_info->flags & (AML_NAMED | AML_FIELD))) {
 435                 return_ACPI_STATUS(AE_OK);
 436         }
 437 
 438         /* Get the object type to determine if we should pop the scope */
 439 
 440         object_type = walk_state->op_info->object_type;
 441 
 442         if (walk_state->op_info->flags & AML_FIELD) {
 443                 /*
 444                  * If we are executing a method, do not create any namespace objects
 445                  * during the load phase, only during execution.
 446                  */
 447                 if (!walk_state->method_node) {
 448                         if (walk_state->opcode == AML_FIELD_OP ||
 449                             walk_state->opcode == AML_BANK_FIELD_OP ||
 450                             walk_state->opcode == AML_INDEX_FIELD_OP) {
 451                                 status =
 452                                     acpi_ds_init_field_objects(op, walk_state);
 453                         }
 454                 }
 455                 return_ACPI_STATUS(status);
 456         }
 457 
 458         /*
 459          * If we are executing a method, do not create any namespace objects
 460          * during the load phase, only during execution.
 461          */
 462         if (!walk_state->method_node) {
 463                 if (op->common.aml_opcode == AML_REGION_OP) {
 464                         status =
 465                             acpi_ex_create_region(op->named.data,
 466                                                   op->named.length,
 467                                                   (acpi_adr_space_type)
 468                                                   ((op->common.value.arg)->
 469                                                    common.value.integer),
 470                                                   walk_state);
 471                         if (ACPI_FAILURE(status)) {
 472                                 return_ACPI_STATUS(status);
 473                         }
 474                 } else if (op->common.aml_opcode == AML_DATA_REGION_OP) {
 475                         status =
 476                             acpi_ex_create_region(op->named.data,
 477                                                   op->named.length,
 478                                                   ACPI_ADR_SPACE_DATA_TABLE,
 479                                                   walk_state);
 480                         if (ACPI_FAILURE(status)) {
 481                                 return_ACPI_STATUS(status);
 482                         }
 483                 }
 484         }
 485 
 486         if (op->common.aml_opcode == AML_NAME_OP) {
 487 
 488                 /* For Name opcode, get the object type from the argument */
 489 
 490                 if (op->common.value.arg) {
 491                         object_type = (acpi_ps_get_opcode_info((op->common.
 492                                                                 value.arg)->
 493                                                                common.
 494                                                                aml_opcode))->
 495                             object_type;
 496 
 497                         /* Set node type if we have a namespace node */
 498 
 499                         if (op->common.node) {
 500                                 op->common.node->type = (u8) object_type;
 501                         }
 502                 }
 503         }
 504 #ifdef ACPI_ASL_COMPILER
 505         /*
 506          * For external opcode, get the object type from the argument and
 507          * get the parameter count from the argument's next.
 508          */
 509         if (acpi_gbl_disasm_flag &&
 510             op->common.node && op->common.aml_opcode == AML_EXTERNAL_OP) {
 511                 /*
 512                  * Note, if this external is not a method
 513                  * Op->Common.Value.Arg->Common.Next->Common.Value.Integer == 0
 514                  * Therefore, param_count will be 0.
 515                  */
 516                 param_count =
 517                     (u8)op->common.value.arg->common.next->common.value.integer;
 518                 object_type = (u8)op->common.value.arg->common.value.integer;
 519                 op->common.node->flags |= ANOBJ_IS_EXTERNAL;
 520                 op->common.node->type = (u8)object_type;
 521 
 522                 acpi_dm_create_subobject_for_external((u8)object_type,
 523                                                       &op->common.node,
 524                                                       param_count);
 525 
 526                 /*
 527                  * Add the external to the external list because we may be
 528                  * emitting code based off of the items within the external list.
 529                  */
 530                 acpi_dm_add_op_to_external_list(op, op->named.path,
 531                                                 (u8)object_type, param_count,
 532                                                 ACPI_EXT_ORIGIN_FROM_OPCODE |
 533                                                 ACPI_EXT_RESOLVED_REFERENCE);
 534         }
 535 #endif
 536 
 537         /*
 538          * If we are executing a method, do not create any namespace objects
 539          * during the load phase, only during execution.
 540          */
 541         if (!walk_state->method_node) {
 542                 if (op->common.aml_opcode == AML_METHOD_OP) {
 543                         /*
 544                          * method_op pkg_length name_string method_flags term_list
 545                          *
 546                          * Note: We must create the method node/object pair as soon as we
 547                          * see the method declaration. This allows later pass1 parsing
 548                          * of invocations of the method (need to know the number of
 549                          * arguments.)
 550                          */
 551                         ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
 552                                           "LOADING-Method: State=%p Op=%p NamedObj=%p\n",
 553                                           walk_state, op, op->named.node));
 554 
 555                         if (!acpi_ns_get_attached_object(op->named.node)) {
 556                                 walk_state->operands[0] =
 557                                     ACPI_CAST_PTR(void, op->named.node);
 558                                 walk_state->num_operands = 1;
 559 
 560                                 status =
 561                                     acpi_ds_create_operands(walk_state,
 562                                                             op->common.value.
 563                                                             arg);
 564                                 if (ACPI_SUCCESS(status)) {
 565                                         status =
 566                                             acpi_ex_create_method(op->named.
 567                                                                   data,
 568                                                                   op->named.
 569                                                                   length,
 570                                                                   walk_state);
 571                                 }
 572 
 573                                 walk_state->operands[0] = NULL;
 574                                 walk_state->num_operands = 0;
 575 
 576                                 if (ACPI_FAILURE(status)) {
 577                                         return_ACPI_STATUS(status);
 578                                 }
 579                         }
 580                 }
 581         }
 582 
 583         /* Pop the scope stack (only if loading a table) */
 584 
 585         if (!walk_state->method_node &&
 586             op->common.aml_opcode != AML_EXTERNAL_OP &&
 587             acpi_ns_opens_scope(object_type)) {
 588                 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH,
 589                                   "(%s): Popping scope for Op %p\n",
 590                                   acpi_ut_get_type_name(object_type), op));
 591 
 592                 status = acpi_ds_scope_stack_pop(walk_state);
 593         }
 594 
 595         return_ACPI_STATUS(status);
 596 }

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