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