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