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