1 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 2 /****************************************************************************** 3 * 4 * Module Name: dswexec - Dispatcher method execution callbacks; 5 * dispatch to interpreter. 6 * 7 * Copyright (C) 2000 - 2023, Intel Corp. 8 * 9 *****************************************************************************/ 10 11 #include <acpi/acpi.h> 12 #include "accommon.h" 13 #include "acparser.h" 14 #include "amlcode.h" 15 #include "acdispat.h" 16 #include "acinterp.h" 17 #include "acnamesp.h" 18 #include "acdebug.h" 19 #ifdef ACPI_EXEC_APP 20 #include "aecommon.h" 21 #endif 22 23 #define _COMPONENT ACPI_DISPATCHER 24 ACPI_MODULE_NAME("dswexec") 25 26 /* 27 * Dispatch table for opcode classes 28 */ 29 static acpi_execute_op acpi_gbl_op_type_dispatch[] = { 30 acpi_ex_opcode_0A_0T_1R, 31 acpi_ex_opcode_1A_0T_0R, 32 acpi_ex_opcode_1A_0T_1R, 33 NULL, /* Was: acpi_ex_opcode_1A_0T_0R (Was for Load operator) */ 34 acpi_ex_opcode_1A_1T_1R, 35 acpi_ex_opcode_2A_0T_0R, 36 acpi_ex_opcode_2A_0T_1R, 37 acpi_ex_opcode_2A_1T_1R, 38 acpi_ex_opcode_2A_2T_1R, 39 acpi_ex_opcode_3A_0T_0R, 40 acpi_ex_opcode_3A_1T_1R, 41 acpi_ex_opcode_6A_0T_1R 42 }; 43 44 /***************************************************************************** 45 * 46 * FUNCTION: acpi_ds_get_predicate_value 47 * 48 * PARAMETERS: walk_state - Current state of the parse tree walk 49 * result_obj - if non-zero, pop result from result stack 50 * 51 * RETURN: Status 52 * 53 * DESCRIPTION: Get the result of a predicate evaluation 54 * 55 ****************************************************************************/ 56 57 acpi_status 58 acpi_ds_get_predicate_value(struct acpi_walk_state *walk_state, 59 union acpi_operand_object *result_obj) 60 { 61 acpi_status status = AE_OK; 62 union acpi_operand_object *obj_desc; 63 union acpi_operand_object *local_obj_desc = NULL; 64 65 ACPI_FUNCTION_TRACE_PTR(ds_get_predicate_value, walk_state); 66 67 walk_state->control_state->common.state = 0; 68 69 if (result_obj) { 70 status = acpi_ds_result_pop(&obj_desc, walk_state); 71 if (ACPI_FAILURE(status)) { 72 ACPI_EXCEPTION((AE_INFO, status, 73 "Could not get result from predicate evaluation")); 74 75 return_ACPI_STATUS(status); 76 } 77 } else { 78 status = acpi_ds_create_operand(walk_state, walk_state->op, 0); 79 if (ACPI_FAILURE(status)) { 80 return_ACPI_STATUS(status); 81 } 82 83 status = 84 acpi_ex_resolve_to_value(&walk_state->operands[0], 85 walk_state); 86 if (ACPI_FAILURE(status)) { 87 return_ACPI_STATUS(status); 88 } 89 90 obj_desc = walk_state->operands[0]; 91 } 92 93 if (!obj_desc) { 94 ACPI_ERROR((AE_INFO, 95 "No predicate ObjDesc=%p State=%p", 96 obj_desc, walk_state)); 97 98 return_ACPI_STATUS(AE_AML_NO_OPERAND); 99 } 100 101 /* 102 * Result of predicate evaluation must be an Integer 103 * object. Implicitly convert the argument if necessary. 104 */ 105 status = acpi_ex_convert_to_integer(obj_desc, &local_obj_desc, 106 ACPI_IMPLICIT_CONVERSION); 107 if (ACPI_FAILURE(status)) { 108 goto cleanup; 109 } 110 111 if (local_obj_desc->common.type != ACPI_TYPE_INTEGER) { 112 ACPI_ERROR((AE_INFO, 113 "Bad predicate (not an integer) ObjDesc=%p State=%p Type=0x%X", 114 obj_desc, walk_state, obj_desc->common.type)); 115 116 status = AE_AML_OPERAND_TYPE; 117 goto cleanup; 118 } 119 120 /* Truncate the predicate to 32-bits if necessary */ 121 122 (void)acpi_ex_truncate_for32bit_table(local_obj_desc); 123 124 /* 125 * Save the result of the predicate evaluation on 126 * the control stack 127 */ 128 if (local_obj_desc->integer.value) { 129 walk_state->control_state->common.value = TRUE; 130 } else { 131 /* 132 * Predicate is FALSE, we will just toss the 133 * rest of the package 134 */ 135 walk_state->control_state->common.value = FALSE; 136 status = AE_CTRL_FALSE; 137 } 138 139 /* Predicate can be used for an implicit return value */ 140 141 (void)acpi_ds_do_implicit_return(local_obj_desc, walk_state, TRUE); 142 143 cleanup: 144 145 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, 146 "Completed a predicate eval=%X Op=%p\n", 147 walk_state->control_state->common.value, 148 walk_state->op)); 149 150 /* Break to debugger to display result */ 151 152 acpi_db_display_result_object(local_obj_desc, walk_state); 153 154 /* 155 * Delete the predicate result object (we know that 156 * we don't need it anymore) 157 */ 158 if (local_obj_desc != obj_desc) { 159 acpi_ut_remove_reference(local_obj_desc); 160 } 161 acpi_ut_remove_reference(obj_desc); 162 163 walk_state->control_state->common.state = ACPI_CONTROL_NORMAL; 164 return_ACPI_STATUS(status); 165 } 166 167 /***************************************************************************** 168 * 169 * FUNCTION: acpi_ds_exec_begin_op 170 * 171 * PARAMETERS: walk_state - Current state of the parse tree walk 172 * out_op - Where to return op if a new one is created 173 * 174 * RETURN: Status 175 * 176 * DESCRIPTION: Descending callback used during the execution of control 177 * methods. This is where most operators and operands are 178 * dispatched to the interpreter. 179 * 180 ****************************************************************************/ 181 182 acpi_status 183 acpi_ds_exec_begin_op(struct acpi_walk_state *walk_state, 184 union acpi_parse_object **out_op) 185 { 186 union acpi_parse_object *op; 187 acpi_status status = AE_OK; 188 u32 opcode_class; 189 190 ACPI_FUNCTION_TRACE_PTR(ds_exec_begin_op, walk_state); 191 192 op = walk_state->op; 193 if (!op) { 194 status = acpi_ds_load2_begin_op(walk_state, out_op); 195 if (ACPI_FAILURE(status)) { 196 goto error_exit; 197 } 198 199 op = *out_op; 200 walk_state->op = op; 201 walk_state->opcode = op->common.aml_opcode; 202 walk_state->op_info = 203 acpi_ps_get_opcode_info(op->common.aml_opcode); 204 205 if (acpi_ns_opens_scope(walk_state->op_info->object_type)) { 206 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, 207 "(%s) Popping scope for Op %p\n", 208 acpi_ut_get_type_name(walk_state-> 209 op_info-> 210 object_type), 211 op)); 212 213 status = acpi_ds_scope_stack_pop(walk_state); 214 if (ACPI_FAILURE(status)) { 215 goto error_exit; 216 } 217 } 218 } 219 220 if (op == walk_state->origin) { 221 if (out_op) { 222 *out_op = op; 223 } 224 225 return_ACPI_STATUS(AE_OK); 226 } 227 228 /* 229 * If the previous opcode was a conditional, this opcode 230 * must be the beginning of the associated predicate. 231 * Save this knowledge in the current scope descriptor 232 */ 233 if ((walk_state->control_state) && 234 (walk_state->control_state->common.state == 235 ACPI_CONTROL_CONDITIONAL_EXECUTING)) { 236 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, 237 "Exec predicate Op=%p State=%p\n", 238 op, walk_state)); 239 240 walk_state->control_state->common.state = 241 ACPI_CONTROL_PREDICATE_EXECUTING; 242 243 /* Save start of predicate */ 244 245 walk_state->control_state->control.predicate_op = op; 246 } 247 248 opcode_class = walk_state->op_info->class; 249 250 /* We want to send namepaths to the load code */ 251 252 if (op->common.aml_opcode == AML_INT_NAMEPATH_OP) { 253 opcode_class = AML_CLASS_NAMED_OBJECT; 254 } 255 256 /* 257 * Handle the opcode based upon the opcode type 258 */ 259 switch (opcode_class) { 260 case AML_CLASS_CONTROL: 261 262 status = acpi_ds_exec_begin_control_op(walk_state, op); 263 break; 264 265 case AML_CLASS_NAMED_OBJECT: 266 267 if (walk_state->walk_type & ACPI_WALK_METHOD) { 268 /* 269 * Found a named object declaration during method execution; 270 * we must enter this object into the namespace. The created 271 * object is temporary and will be deleted upon completion of 272 * the execution of this method. 273 * 274 * Note 10/2010: Except for the Scope() op. This opcode does 275 * not actually create a new object, it refers to an existing 276 * object. However, for Scope(), we want to indeed open a 277 * new scope. 278 */ 279 if (op->common.aml_opcode != AML_SCOPE_OP) { 280 status = 281 acpi_ds_load2_begin_op(walk_state, NULL); 282 } else { 283 status = 284 acpi_ds_scope_stack_push(op->named.node, 285 op->named.node-> 286 type, walk_state); 287 if (ACPI_FAILURE(status)) { 288 return_ACPI_STATUS(status); 289 } 290 } 291 } 292 break; 293 294 case AML_CLASS_EXECUTE: 295 case AML_CLASS_CREATE: 296 297 break; 298 299 default: 300 301 break; 302 } 303 304 /* Nothing to do here during method execution */ 305 306 return_ACPI_STATUS(status); 307 308 error_exit: 309 status = acpi_ds_method_error(status, walk_state); 310 return_ACPI_STATUS(status); 311 } 312 313 /***************************************************************************** 314 * 315 * FUNCTION: acpi_ds_exec_end_op 316 * 317 * PARAMETERS: walk_state - Current state of the parse tree walk 318 * 319 * RETURN: Status 320 * 321 * DESCRIPTION: Ascending callback used during the execution of control 322 * methods. The only thing we really need to do here is to 323 * notice the beginning of IF, ELSE, and WHILE blocks. 324 * 325 ****************************************************************************/ 326 327 acpi_status acpi_ds_exec_end_op(struct acpi_walk_state *walk_state) 328 { 329 union acpi_parse_object *op; 330 acpi_status status = AE_OK; 331 u32 op_type; 332 u32 op_class; 333 union acpi_parse_object *next_op; 334 union acpi_parse_object *first_arg; 335 #ifdef ACPI_EXEC_APP 336 char *namepath; 337 union acpi_operand_object *obj_desc; 338 #endif 339 340 ACPI_FUNCTION_TRACE_PTR(ds_exec_end_op, walk_state); 341 342 op = walk_state->op; 343 op_type = walk_state->op_info->type; 344 op_class = walk_state->op_info->class; 345 346 if (op_class == AML_CLASS_UNKNOWN) { 347 ACPI_ERROR((AE_INFO, "Unknown opcode 0x%X", 348 op->common.aml_opcode)); 349 return_ACPI_STATUS(AE_NOT_IMPLEMENTED); 350 } 351 352 first_arg = op->common.value.arg; 353 354 /* Init the walk state */ 355 356 walk_state->num_operands = 0; 357 walk_state->operand_index = 0; 358 walk_state->return_desc = NULL; 359 walk_state->result_obj = NULL; 360 361 /* Call debugger for single step support (DEBUG build only) */ 362 363 status = acpi_db_single_step(walk_state, op, op_class); 364 if (ACPI_FAILURE(status)) { 365 return_ACPI_STATUS(status); 366 } 367 368 /* Decode the Opcode Class */ 369 370 switch (op_class) { 371 case AML_CLASS_ARGUMENT: /* Constants, literals, etc. */ 372 373 if (walk_state->opcode == AML_INT_NAMEPATH_OP) { 374 status = acpi_ds_evaluate_name_path(walk_state); 375 if (ACPI_FAILURE(status)) { 376 goto cleanup; 377 } 378 } 379 break; 380 381 case AML_CLASS_EXECUTE: /* Most operators with arguments */ 382 383 /* Build resolved operand stack */ 384 385 status = acpi_ds_create_operands(walk_state, first_arg); 386 if (ACPI_FAILURE(status)) { 387 goto cleanup; 388 } 389 390 /* 391 * All opcodes require operand resolution, with the only exceptions 392 * being the object_type and size_of operators as well as opcodes that 393 * take no arguments. 394 */ 395 if (!(walk_state->op_info->flags & AML_NO_OPERAND_RESOLVE) && 396 (walk_state->op_info->flags & AML_HAS_ARGS)) { 397 398 /* Resolve all operands */ 399 400 status = acpi_ex_resolve_operands(walk_state->opcode, 401 &(walk_state-> 402 operands 403 [walk_state-> 404 num_operands - 1]), 405 walk_state); 406 } 407 408 if (ACPI_SUCCESS(status)) { 409 /* 410 * Dispatch the request to the appropriate interpreter handler 411 * routine. There is one routine per opcode "type" based upon the 412 * number of opcode arguments and return type. 413 */ 414 status = 415 acpi_gbl_op_type_dispatch[op_type] (walk_state); 416 } else { 417 /* 418 * Treat constructs of the form "Store(LocalX,LocalX)" as noops when the 419 * Local is uninitialized. 420 */ 421 if ((status == AE_AML_UNINITIALIZED_LOCAL) && 422 (walk_state->opcode == AML_STORE_OP) && 423 (walk_state->operands[0]->common.type == 424 ACPI_TYPE_LOCAL_REFERENCE) 425 && (walk_state->operands[1]->common.type == 426 ACPI_TYPE_LOCAL_REFERENCE) 427 && (walk_state->operands[0]->reference.class == 428 walk_state->operands[1]->reference.class) 429 && (walk_state->operands[0]->reference.value == 430 walk_state->operands[1]->reference.value)) { 431 status = AE_OK; 432 } else { 433 ACPI_EXCEPTION((AE_INFO, status, 434 "While resolving operands for [%s]", 435 acpi_ps_get_opcode_name 436 (walk_state->opcode))); 437 } 438 } 439 440 /* Always delete the argument objects and clear the operand stack */ 441 442 acpi_ds_clear_operands(walk_state); 443 444 /* 445 * If a result object was returned from above, push it on the 446 * current result stack 447 */ 448 if (ACPI_SUCCESS(status) && walk_state->result_obj) { 449 status = 450 acpi_ds_result_push(walk_state->result_obj, 451 walk_state); 452 } 453 break; 454 455 default: 456 457 switch (op_type) { 458 case AML_TYPE_CONTROL: /* Type 1 opcode, IF/ELSE/WHILE/NOOP */ 459 460 /* 1 Operand, 0 external_result, 0 internal_result */ 461 462 status = acpi_ds_exec_end_control_op(walk_state, op); 463 464 break; 465 466 case AML_TYPE_METHOD_CALL: 467 /* 468 * If the method is referenced from within a package 469 * declaration, it is not a invocation of the method, just 470 * a reference to it. 471 */ 472 if ((op->asl.parent) && 473 ((op->asl.parent->asl.aml_opcode == AML_PACKAGE_OP) 474 || (op->asl.parent->asl.aml_opcode == 475 AML_VARIABLE_PACKAGE_OP))) { 476 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, 477 "Method Reference in a Package, Op=%p\n", 478 op)); 479 480 op->common.node = (struct acpi_namespace_node *) 481 op->asl.value.arg->asl.node; 482 acpi_ut_add_reference(op->asl.value.arg->asl. 483 node->object); 484 return_ACPI_STATUS(AE_OK); 485 } 486 487 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, 488 "Method invocation, Op=%p\n", op)); 489 490 /* 491 * (AML_METHODCALL) Op->Asl.Value.Arg->Asl.Node contains 492 * the method Node pointer 493 */ 494 /* next_op points to the op that holds the method name */ 495 496 next_op = first_arg; 497 498 /* next_op points to first argument op */ 499 500 next_op = next_op->common.next; 501 502 /* 503 * Get the method's arguments and put them on the operand stack 504 */ 505 status = acpi_ds_create_operands(walk_state, next_op); 506 if (ACPI_FAILURE(status)) { 507 break; 508 } 509 510 /* 511 * Since the operands will be passed to another control method, 512 * we must resolve all local references here (Local variables, 513 * arguments to *this* method, etc.) 514 */ 515 status = acpi_ds_resolve_operands(walk_state); 516 if (ACPI_FAILURE(status)) { 517 518 /* On error, clear all resolved operands */ 519 520 acpi_ds_clear_operands(walk_state); 521 break; 522 } 523 524 /* 525 * Tell the walk loop to preempt this running method and 526 * execute the new method 527 */ 528 status = AE_CTRL_TRANSFER; 529 530 /* 531 * Return now; we don't want to disturb anything, 532 * especially the operand count! 533 */ 534 return_ACPI_STATUS(status); 535 536 case AML_TYPE_CREATE_FIELD: 537 538 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, 539 "Executing CreateField Buffer/Index Op=%p\n", 540 op)); 541 542 status = acpi_ds_load2_end_op(walk_state); 543 if (ACPI_FAILURE(status)) { 544 break; 545 } 546 547 status = 548 acpi_ds_eval_buffer_field_operands(walk_state, op); 549 if (ACPI_FAILURE(status)) { 550 break; 551 } 552 #ifdef ACPI_EXEC_APP 553 /* 554 * acpi_exec support for namespace initialization file (initialize 555 * buffer_fields in this code.) 556 */ 557 namepath = 558 acpi_ns_get_external_pathname(op->common.node); 559 status = ae_lookup_init_file_entry(namepath, &obj_desc); 560 if (ACPI_SUCCESS(status)) { 561 status = 562 acpi_ex_write_data_to_field(obj_desc, 563 op->common. 564 node->object, 565 NULL); 566 if (ACPI_FAILURE(status)) { 567 ACPI_EXCEPTION((AE_INFO, status, 568 "While writing to buffer field")); 569 } 570 } 571 ACPI_FREE(namepath); 572 status = AE_OK; 573 #endif 574 break; 575 576 case AML_TYPE_CREATE_OBJECT: 577 578 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, 579 "Executing CreateObject (Buffer/Package) Op=%p Child=%p ParentOpcode=%4.4X\n", 580 op, op->named.value.arg, 581 op->common.parent->common. 582 aml_opcode)); 583 584 switch (op->common.parent->common.aml_opcode) { 585 case AML_NAME_OP: 586 /* 587 * Put the Node on the object stack (Contains the ACPI Name 588 * of this object) 589 */ 590 walk_state->operands[0] = (void *) 591 op->common.parent->common.node; 592 walk_state->num_operands = 1; 593 594 status = acpi_ds_create_node(walk_state, 595 op->common.parent-> 596 common.node, 597 op->common.parent); 598 if (ACPI_FAILURE(status)) { 599 break; 600 } 601 602 ACPI_FALLTHROUGH; 603 604 case AML_INT_EVAL_SUBTREE_OP: 605 606 status = 607 acpi_ds_eval_data_object_operands 608 (walk_state, op, 609 acpi_ns_get_attached_object(op->common. 610 parent->common. 611 node)); 612 break; 613 614 default: 615 616 status = 617 acpi_ds_eval_data_object_operands 618 (walk_state, op, NULL); 619 break; 620 } 621 622 /* 623 * If a result object was returned from above, push it on the 624 * current result stack 625 */ 626 if (walk_state->result_obj) { 627 status = 628 acpi_ds_result_push(walk_state->result_obj, 629 walk_state); 630 } 631 break; 632 633 case AML_TYPE_NAMED_FIELD: 634 case AML_TYPE_NAMED_COMPLEX: 635 case AML_TYPE_NAMED_SIMPLE: 636 case AML_TYPE_NAMED_NO_OBJ: 637 638 status = acpi_ds_load2_end_op(walk_state); 639 if (ACPI_FAILURE(status)) { 640 break; 641 } 642 643 if (op->common.aml_opcode == AML_REGION_OP) { 644 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, 645 "Executing OpRegion Address/Length Op=%p\n", 646 op)); 647 648 status = 649 acpi_ds_eval_region_operands(walk_state, 650 op); 651 if (ACPI_FAILURE(status)) { 652 break; 653 } 654 } else if (op->common.aml_opcode == AML_DATA_REGION_OP) { 655 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, 656 "Executing DataTableRegion Strings Op=%p\n", 657 op)); 658 659 status = 660 acpi_ds_eval_table_region_operands 661 (walk_state, op); 662 if (ACPI_FAILURE(status)) { 663 break; 664 } 665 } else if (op->common.aml_opcode == AML_BANK_FIELD_OP) { 666 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, 667 "Executing BankField Op=%p\n", 668 op)); 669 670 status = 671 acpi_ds_eval_bank_field_operands(walk_state, 672 op); 673 if (ACPI_FAILURE(status)) { 674 break; 675 } 676 } 677 break; 678 679 case AML_TYPE_UNDEFINED: 680 681 ACPI_ERROR((AE_INFO, 682 "Undefined opcode type Op=%p", op)); 683 return_ACPI_STATUS(AE_NOT_IMPLEMENTED); 684 685 case AML_TYPE_BOGUS: 686 687 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, 688 "Internal opcode=%X type Op=%p\n", 689 walk_state->opcode, op)); 690 break; 691 692 default: 693 694 ACPI_ERROR((AE_INFO, 695 "Unimplemented opcode, class=0x%X " 696 "type=0x%X Opcode=0x%X Op=%p", 697 op_class, op_type, op->common.aml_opcode, 698 op)); 699 700 status = AE_NOT_IMPLEMENTED; 701 break; 702 } 703 } 704 705 /* 706 * ACPI 2.0 support for 64-bit integers: Truncate numeric 707 * result value if we are executing from a 32-bit ACPI table 708 */ 709 (void)acpi_ex_truncate_for32bit_table(walk_state->result_obj); 710 711 /* 712 * Check if we just completed the evaluation of a 713 * conditional predicate 714 */ 715 if ((ACPI_SUCCESS(status)) && 716 (walk_state->control_state) && 717 (walk_state->control_state->common.state == 718 ACPI_CONTROL_PREDICATE_EXECUTING) && 719 (walk_state->control_state->control.predicate_op == op)) { 720 status = 721 acpi_ds_get_predicate_value(walk_state, 722 walk_state->result_obj); 723 walk_state->result_obj = NULL; 724 } 725 726 cleanup: 727 728 if (walk_state->result_obj) { 729 730 /* Break to debugger to display result */ 731 732 acpi_db_display_result_object(walk_state->result_obj, 733 walk_state); 734 735 /* 736 * Delete the result op if and only if: 737 * Parent will not use the result -- such as any 738 * non-nested type2 op in a method (parent will be method) 739 */ 740 acpi_ds_delete_result_if_not_used(op, walk_state->result_obj, 741 walk_state); 742 } 743 #ifdef _UNDER_DEVELOPMENT 744 745 if (walk_state->parser_state.aml == walk_state->parser_state.aml_end) { 746 acpi_db_method_end(walk_state); 747 } 748 #endif 749 750 /* Invoke exception handler on error */ 751 752 if (ACPI_FAILURE(status)) { 753 status = acpi_ds_method_error(status, walk_state); 754 } 755 756 /* Always clear the object stack */ 757 758 walk_state->num_operands = 0; 759 return_ACPI_STATUS(status); 760 } 761