1 /****************************************************************************** 2 * 3 * Module Name: dsopcode - Dispatcher Op Region support and handling of 4 * "control" opcodes 5 * 6 *****************************************************************************/ 7 8 /* 9 * Copyright (C) 2000 - 2008, Intel Corp. 10 * All rights reserved. 11 * 12 * Redistribution and use in source and binary forms, with or without 13 * modification, are permitted provided that the following conditions 14 * are met: 15 * 1. Redistributions of source code must retain the above copyright 16 * notice, this list of conditions, and the following disclaimer, 17 * without modification. 18 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 19 * substantially similar to the "NO WARRANTY" disclaimer below 20 * ("Disclaimer") and any redistribution must be conditioned upon 21 * including a substantially similar Disclaimer requirement for further 22 * binary redistribution. 23 * 3. Neither the names of the above-listed copyright holders nor the names 24 * of any contributors may be used to endorse or promote products derived 25 * from this software without specific prior written permission. 26 * 27 * Alternatively, this software may be distributed under the terms of the 28 * GNU General Public License ("GPL") version 2 as published by the Free 29 * Software Foundation. 30 * 31 * NO WARRANTY 32 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 33 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 34 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 35 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 36 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 37 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 38 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 39 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 40 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 41 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 42 * POSSIBILITY OF SUCH DAMAGES. 43 */ 44 45 #include <acpi/acpi.h> 46 #include "accommon.h" 47 #include "acparser.h" 48 #include "amlcode.h" 49 #include "acdispat.h" 50 #include "acinterp.h" 51 #include "acnamesp.h" 52 #include "acevents.h" 53 #include "actables.h" 54 55 #define _COMPONENT ACPI_DISPATCHER 56 ACPI_MODULE_NAME("dsopcode") 57 58 /* Local prototypes */ 59 static acpi_status 60 acpi_ds_execute_arguments(struct acpi_namespace_node *node, 61 struct acpi_namespace_node *scope_node, 62 u32 aml_length, u8 * aml_start); 63 64 static acpi_status 65 acpi_ds_init_buffer_field(u16 aml_opcode, 66 union acpi_operand_object *obj_desc, 67 union acpi_operand_object *buffer_desc, 68 union acpi_operand_object *offset_desc, 69 union acpi_operand_object *length_desc, 70 union acpi_operand_object *result_desc); 71 72 /******************************************************************************* 73 * 74 * FUNCTION: acpi_ds_execute_arguments 75 * 76 * PARAMETERS: Node - Object NS node 77 * scope_node - Parent NS node 78 * aml_length - Length of executable AML 79 * aml_start - Pointer to the AML 80 * 81 * RETURN: Status. 82 * 83 * DESCRIPTION: Late (deferred) execution of region or field arguments 84 * 85 ******************************************************************************/ 86 87 static acpi_status 88 acpi_ds_execute_arguments(struct acpi_namespace_node *node, 89 struct acpi_namespace_node *scope_node, 90 u32 aml_length, u8 * aml_start) 91 { 92 acpi_status status; 93 union acpi_parse_object *op; 94 struct acpi_walk_state *walk_state; 95 96 ACPI_FUNCTION_TRACE(ds_execute_arguments); 97 98 /* 99 * Allocate a new parser op to be the root of the parsed tree 100 */ 101 op = acpi_ps_alloc_op(AML_INT_EVAL_SUBTREE_OP); 102 if (!op) { 103 return_ACPI_STATUS(AE_NO_MEMORY); 104 } 105 106 /* Save the Node for use in acpi_ps_parse_aml */ 107 108 op->common.node = scope_node; 109 110 /* Create and initialize a new parser state */ 111 112 walk_state = acpi_ds_create_walk_state(0, NULL, NULL, NULL); 113 if (!walk_state) { 114 status = AE_NO_MEMORY; 115 goto cleanup; 116 } 117 118 status = acpi_ds_init_aml_walk(walk_state, op, NULL, aml_start, 119 aml_length, NULL, ACPI_IMODE_LOAD_PASS1); 120 if (ACPI_FAILURE(status)) { 121 acpi_ds_delete_walk_state(walk_state); 122 goto cleanup; 123 } 124 125 /* Mark this parse as a deferred opcode */ 126 127 walk_state->parse_flags = ACPI_PARSE_DEFERRED_OP; 128 walk_state->deferred_node = node; 129 130 /* Pass1: Parse the entire declaration */ 131 132 status = acpi_ps_parse_aml(walk_state); 133 if (ACPI_FAILURE(status)) { 134 goto cleanup; 135 } 136 137 /* Get and init the Op created above */ 138 139 op->common.node = node; 140 acpi_ps_delete_parse_tree(op); 141 142 /* Evaluate the deferred arguments */ 143 144 op = acpi_ps_alloc_op(AML_INT_EVAL_SUBTREE_OP); 145 if (!op) { 146 return_ACPI_STATUS(AE_NO_MEMORY); 147 } 148 149 op->common.node = scope_node; 150 151 /* Create and initialize a new parser state */ 152 153 walk_state = acpi_ds_create_walk_state(0, NULL, NULL, NULL); 154 if (!walk_state) { 155 status = AE_NO_MEMORY; 156 goto cleanup; 157 } 158 159 /* Execute the opcode and arguments */ 160 161 status = acpi_ds_init_aml_walk(walk_state, op, NULL, aml_start, 162 aml_length, NULL, ACPI_IMODE_EXECUTE); 163 if (ACPI_FAILURE(status)) { 164 acpi_ds_delete_walk_state(walk_state); 165 goto cleanup; 166 } 167 168 /* Mark this execution as a deferred opcode */ 169 170 walk_state->deferred_node = node; 171 status = acpi_ps_parse_aml(walk_state); 172 173 cleanup: 174 acpi_ps_delete_parse_tree(op); 175 return_ACPI_STATUS(status); 176 } 177 178 /******************************************************************************* 179 * 180 * FUNCTION: acpi_ds_get_buffer_field_arguments 181 * 182 * PARAMETERS: obj_desc - A valid buffer_field object 183 * 184 * RETURN: Status. 185 * 186 * DESCRIPTION: Get buffer_field Buffer and Index. This implements the late 187 * evaluation of these field attributes. 188 * 189 ******************************************************************************/ 190 191 acpi_status 192 acpi_ds_get_buffer_field_arguments(union acpi_operand_object *obj_desc) 193 { 194 union acpi_operand_object *extra_desc; 195 struct acpi_namespace_node *node; 196 acpi_status status; 197 198 ACPI_FUNCTION_TRACE_PTR(ds_get_buffer_field_arguments, obj_desc); 199 200 if (obj_desc->common.flags & AOPOBJ_DATA_VALID) { 201 return_ACPI_STATUS(AE_OK); 202 } 203 204 /* Get the AML pointer (method object) and buffer_field node */ 205 206 extra_desc = acpi_ns_get_secondary_object(obj_desc); 207 node = obj_desc->buffer_field.node; 208 209 ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname 210 (ACPI_TYPE_BUFFER_FIELD, node, NULL)); 211 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "[%4.4s] BufferField Arg Init\n", 212 acpi_ut_get_node_name(node))); 213 214 /* Execute the AML code for the term_arg arguments */ 215 216 status = acpi_ds_execute_arguments(node, acpi_ns_get_parent_node(node), 217 extra_desc->extra.aml_length, 218 extra_desc->extra.aml_start); 219 return_ACPI_STATUS(status); 220 } 221 222 /******************************************************************************* 223 * 224 * FUNCTION: acpi_ds_get_bank_field_arguments 225 * 226 * PARAMETERS: obj_desc - A valid bank_field object 227 * 228 * RETURN: Status. 229 * 230 * DESCRIPTION: Get bank_field bank_value. This implements the late 231 * evaluation of these field attributes. 232 * 233 ******************************************************************************/ 234 235 acpi_status 236 acpi_ds_get_bank_field_arguments(union acpi_operand_object *obj_desc) 237 { 238 union acpi_operand_object *extra_desc; 239 struct acpi_namespace_node *node; 240 acpi_status status; 241 242 ACPI_FUNCTION_TRACE_PTR(ds_get_bank_field_arguments, obj_desc); 243 244 if (obj_desc->common.flags & AOPOBJ_DATA_VALID) { 245 return_ACPI_STATUS(AE_OK); 246 } 247 248 /* Get the AML pointer (method object) and bank_field node */ 249 250 extra_desc = acpi_ns_get_secondary_object(obj_desc); 251 node = obj_desc->bank_field.node; 252 253 ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname 254 (ACPI_TYPE_LOCAL_BANK_FIELD, node, NULL)); 255 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "[%4.4s] BankField Arg Init\n", 256 acpi_ut_get_node_name(node))); 257 258 /* Execute the AML code for the term_arg arguments */ 259 260 status = acpi_ds_execute_arguments(node, acpi_ns_get_parent_node(node), 261 extra_desc->extra.aml_length, 262 extra_desc->extra.aml_start); 263 return_ACPI_STATUS(status); 264 } 265 266 /******************************************************************************* 267 * 268 * FUNCTION: acpi_ds_get_buffer_arguments 269 * 270 * PARAMETERS: obj_desc - A valid Buffer object 271 * 272 * RETURN: Status. 273 * 274 * DESCRIPTION: Get Buffer length and initializer byte list. This implements 275 * the late evaluation of these attributes. 276 * 277 ******************************************************************************/ 278 279 acpi_status acpi_ds_get_buffer_arguments(union acpi_operand_object *obj_desc) 280 { 281 struct acpi_namespace_node *node; 282 acpi_status status; 283 284 ACPI_FUNCTION_TRACE_PTR(ds_get_buffer_arguments, obj_desc); 285 286 if (obj_desc->common.flags & AOPOBJ_DATA_VALID) { 287 return_ACPI_STATUS(AE_OK); 288 } 289 290 /* Get the Buffer node */ 291 292 node = obj_desc->buffer.node; 293 if (!node) { 294 ACPI_ERROR((AE_INFO, 295 "No pointer back to NS node in buffer obj %p", 296 obj_desc)); 297 return_ACPI_STATUS(AE_AML_INTERNAL); 298 } 299 300 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Buffer Arg Init\n")); 301 302 /* Execute the AML code for the term_arg arguments */ 303 304 status = acpi_ds_execute_arguments(node, node, 305 obj_desc->buffer.aml_length, 306 obj_desc->buffer.aml_start); 307 return_ACPI_STATUS(status); 308 } 309 310 /******************************************************************************* 311 * 312 * FUNCTION: acpi_ds_get_package_arguments 313 * 314 * PARAMETERS: obj_desc - A valid Package object 315 * 316 * RETURN: Status. 317 * 318 * DESCRIPTION: Get Package length and initializer byte list. This implements 319 * the late evaluation of these attributes. 320 * 321 ******************************************************************************/ 322 323 acpi_status acpi_ds_get_package_arguments(union acpi_operand_object *obj_desc) 324 { 325 struct acpi_namespace_node *node; 326 acpi_status status; 327 328 ACPI_FUNCTION_TRACE_PTR(ds_get_package_arguments, obj_desc); 329 330 if (obj_desc->common.flags & AOPOBJ_DATA_VALID) { 331 return_ACPI_STATUS(AE_OK); 332 } 333 334 /* Get the Package node */ 335 336 node = obj_desc->package.node; 337 if (!node) { 338 ACPI_ERROR((AE_INFO, 339 "No pointer back to NS node in package %p", 340 obj_desc)); 341 return_ACPI_STATUS(AE_AML_INTERNAL); 342 } 343 344 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Package Arg Init\n")); 345 346 /* Execute the AML code for the term_arg arguments */ 347 348 status = acpi_ds_execute_arguments(node, node, 349 obj_desc->package.aml_length, 350 obj_desc->package.aml_start); 351 return_ACPI_STATUS(status); 352 } 353 354 /***************************************************************************** 355 * 356 * FUNCTION: acpi_ds_get_region_arguments 357 * 358 * PARAMETERS: obj_desc - A valid region object 359 * 360 * RETURN: Status. 361 * 362 * DESCRIPTION: Get region address and length. This implements the late 363 * evaluation of these region attributes. 364 * 365 ****************************************************************************/ 366 367 acpi_status acpi_ds_get_region_arguments(union acpi_operand_object *obj_desc) 368 { 369 struct acpi_namespace_node *node; 370 acpi_status status; 371 union acpi_operand_object *extra_desc; 372 373 ACPI_FUNCTION_TRACE_PTR(ds_get_region_arguments, obj_desc); 374 375 if (obj_desc->region.flags & AOPOBJ_DATA_VALID) { 376 return_ACPI_STATUS(AE_OK); 377 } 378 379 extra_desc = acpi_ns_get_secondary_object(obj_desc); 380 if (!extra_desc) { 381 return_ACPI_STATUS(AE_NOT_EXIST); 382 } 383 384 /* Get the Region node */ 385 386 node = obj_desc->region.node; 387 388 ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname 389 (ACPI_TYPE_REGION, node, NULL)); 390 391 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "[%4.4s] OpRegion Arg Init at AML %p\n", 392 acpi_ut_get_node_name(node), 393 extra_desc->extra.aml_start)); 394 395 /* Execute the argument AML */ 396 397 status = acpi_ds_execute_arguments(node, acpi_ns_get_parent_node(node), 398 extra_desc->extra.aml_length, 399 extra_desc->extra.aml_start); 400 return_ACPI_STATUS(status); 401 } 402 403 /******************************************************************************* 404 * 405 * FUNCTION: acpi_ds_initialize_region 406 * 407 * PARAMETERS: obj_handle - Region namespace node 408 * 409 * RETURN: Status 410 * 411 * DESCRIPTION: Front end to ev_initialize_region 412 * 413 ******************************************************************************/ 414 415 acpi_status acpi_ds_initialize_region(acpi_handle obj_handle) 416 { 417 union acpi_operand_object *obj_desc; 418 acpi_status status; 419 420 obj_desc = acpi_ns_get_attached_object(obj_handle); 421 422 /* Namespace is NOT locked */ 423 424 status = acpi_ev_initialize_region(obj_desc, FALSE); 425 return (status); 426 } 427 428 /******************************************************************************* 429 * 430 * FUNCTION: acpi_ds_init_buffer_field 431 * 432 * PARAMETERS: aml_opcode - create_xxx_field 433 * obj_desc - buffer_field object 434 * buffer_desc - Host Buffer 435 * offset_desc - Offset into buffer 436 * length_desc - Length of field (CREATE_FIELD_OP only) 437 * result_desc - Where to store the result 438 * 439 * RETURN: Status 440 * 441 * DESCRIPTION: Perform actual initialization of a buffer field 442 * 443 ******************************************************************************/ 444 445 static acpi_status 446 acpi_ds_init_buffer_field(u16 aml_opcode, 447 union acpi_operand_object *obj_desc, 448 union acpi_operand_object *buffer_desc, 449 union acpi_operand_object *offset_desc, 450 union acpi_operand_object *length_desc, 451 union acpi_operand_object *result_desc) 452 { 453 u32 offset; 454 u32 bit_offset; 455 u32 bit_count; 456 u8 field_flags; 457 acpi_status status; 458 459 ACPI_FUNCTION_TRACE_PTR(ds_init_buffer_field, obj_desc); 460 461 /* Host object must be a Buffer */ 462 463 if (buffer_desc->common.type != ACPI_TYPE_BUFFER) { 464 ACPI_ERROR((AE_INFO, 465 "Target of Create Field is not a Buffer object - %s", 466 acpi_ut_get_object_type_name(buffer_desc))); 467 468 status = AE_AML_OPERAND_TYPE; 469 goto cleanup; 470 } 471 472 /* 473 * The last parameter to all of these opcodes (result_desc) started 474 * out as a name_string, and should therefore now be a NS node 475 * after resolution in acpi_ex_resolve_operands(). 476 */ 477 if (ACPI_GET_DESCRIPTOR_TYPE(result_desc) != ACPI_DESC_TYPE_NAMED) { 478 ACPI_ERROR((AE_INFO, 479 "(%s) destination not a NS Node [%s]", 480 acpi_ps_get_opcode_name(aml_opcode), 481 acpi_ut_get_descriptor_name(result_desc))); 482 483 status = AE_AML_OPERAND_TYPE; 484 goto cleanup; 485 } 486 487 offset = (u32) offset_desc->integer.value; 488 489 /* 490 * Setup the Bit offsets and counts, according to the opcode 491 */ 492 switch (aml_opcode) { 493 case AML_CREATE_FIELD_OP: 494 495 /* Offset is in bits, count is in bits */ 496 497 field_flags = AML_FIELD_ACCESS_BYTE; 498 bit_offset = offset; 499 bit_count = (u32) length_desc->integer.value; 500 501 /* Must have a valid (>0) bit count */ 502 503 if (bit_count == 0) { 504 ACPI_ERROR((AE_INFO, 505 "Attempt to CreateField of length zero")); 506 status = AE_AML_OPERAND_VALUE; 507 goto cleanup; 508 } 509 break; 510 511 case AML_CREATE_BIT_FIELD_OP: 512 513 /* Offset is in bits, Field is one bit */ 514 515 bit_offset = offset; 516 bit_count = 1; 517 field_flags = AML_FIELD_ACCESS_BYTE; 518 break; 519 520 case AML_CREATE_BYTE_FIELD_OP: 521 522 /* Offset is in bytes, field is one byte */ 523 524 bit_offset = 8 * offset; 525 bit_count = 8; 526 field_flags = AML_FIELD_ACCESS_BYTE; 527 break; 528 529 case AML_CREATE_WORD_FIELD_OP: 530 531 /* Offset is in bytes, field is one word */ 532 533 bit_offset = 8 * offset; 534 bit_count = 16; 535 field_flags = AML_FIELD_ACCESS_WORD; 536 break; 537 538 case AML_CREATE_DWORD_FIELD_OP: 539 540 /* Offset is in bytes, field is one dword */ 541 542 bit_offset = 8 * offset; 543 bit_count = 32; 544 field_flags = AML_FIELD_ACCESS_DWORD; 545 break; 546 547 case AML_CREATE_QWORD_FIELD_OP: 548 549 /* Offset is in bytes, field is one qword */ 550 551 bit_offset = 8 * offset; 552 bit_count = 64; 553 field_flags = AML_FIELD_ACCESS_QWORD; 554 break; 555 556 default: 557 558 ACPI_ERROR((AE_INFO, 559 "Unknown field creation opcode %02x", aml_opcode)); 560 status = AE_AML_BAD_OPCODE; 561 goto cleanup; 562 } 563 564 /* Entire field must fit within the current length of the buffer */ 565 566 if ((bit_offset + bit_count) > (8 * (u32) buffer_desc->buffer.length)) { 567 ACPI_ERROR((AE_INFO, 568 "Field [%4.4s] at %d exceeds Buffer [%4.4s] size %d (bits)", 569 acpi_ut_get_node_name(result_desc), 570 bit_offset + bit_count, 571 acpi_ut_get_node_name(buffer_desc->buffer.node), 572 8 * (u32) buffer_desc->buffer.length)); 573 status = AE_AML_BUFFER_LIMIT; 574 goto cleanup; 575 } 576 577 /* 578 * Initialize areas of the field object that are common to all fields 579 * For field_flags, use LOCK_RULE = 0 (NO_LOCK), 580 * UPDATE_RULE = 0 (UPDATE_PRESERVE) 581 */ 582 status = acpi_ex_prep_common_field_object(obj_desc, field_flags, 0, 583 bit_offset, bit_count); 584 if (ACPI_FAILURE(status)) { 585 goto cleanup; 586 } 587 588 obj_desc->buffer_field.buffer_obj = buffer_desc; 589 590 /* Reference count for buffer_desc inherits obj_desc count */ 591 592 buffer_desc->common.reference_count = (u16) 593 (buffer_desc->common.reference_count + 594 obj_desc->common.reference_count); 595 596 cleanup: 597 598 /* Always delete the operands */ 599 600 acpi_ut_remove_reference(offset_desc); 601 acpi_ut_remove_reference(buffer_desc); 602 603 if (aml_opcode == AML_CREATE_FIELD_OP) { 604 acpi_ut_remove_reference(length_desc); 605 } 606 607 /* On failure, delete the result descriptor */ 608 609 if (ACPI_FAILURE(status)) { 610 acpi_ut_remove_reference(result_desc); /* Result descriptor */ 611 } else { 612 /* Now the address and length are valid for this buffer_field */ 613 614 obj_desc->buffer_field.flags |= AOPOBJ_DATA_VALID; 615 } 616 617 return_ACPI_STATUS(status); 618 } 619 620 /******************************************************************************* 621 * 622 * FUNCTION: acpi_ds_eval_buffer_field_operands 623 * 624 * PARAMETERS: walk_state - Current walk 625 * Op - A valid buffer_field Op object 626 * 627 * RETURN: Status 628 * 629 * DESCRIPTION: Get buffer_field Buffer and Index 630 * Called from acpi_ds_exec_end_op during buffer_field parse tree walk 631 * 632 ******************************************************************************/ 633 634 acpi_status 635 acpi_ds_eval_buffer_field_operands(struct acpi_walk_state *walk_state, 636 union acpi_parse_object *op) 637 { 638 acpi_status status; 639 union acpi_operand_object *obj_desc; 640 struct acpi_namespace_node *node; 641 union acpi_parse_object *next_op; 642 643 ACPI_FUNCTION_TRACE_PTR(ds_eval_buffer_field_operands, op); 644 645 /* 646 * This is where we evaluate the address and length fields of the 647 * create_xxx_field declaration 648 */ 649 node = op->common.node; 650 651 /* next_op points to the op that holds the Buffer */ 652 653 next_op = op->common.value.arg; 654 655 /* Evaluate/create the address and length operands */ 656 657 status = acpi_ds_create_operands(walk_state, next_op); 658 if (ACPI_FAILURE(status)) { 659 return_ACPI_STATUS(status); 660 } 661 662 obj_desc = acpi_ns_get_attached_object(node); 663 if (!obj_desc) { 664 return_ACPI_STATUS(AE_NOT_EXIST); 665 } 666 667 /* Resolve the operands */ 668 669 status = acpi_ex_resolve_operands(op->common.aml_opcode, 670 ACPI_WALK_OPERANDS, walk_state); 671 if (ACPI_FAILURE(status)) { 672 ACPI_ERROR((AE_INFO, "(%s) bad operand(s) (%X)", 673 acpi_ps_get_opcode_name(op->common.aml_opcode), 674 status)); 675 676 return_ACPI_STATUS(status); 677 } 678 679 /* Initialize the Buffer Field */ 680 681 if (op->common.aml_opcode == AML_CREATE_FIELD_OP) { 682 683 /* NOTE: Slightly different operands for this opcode */ 684 685 status = 686 acpi_ds_init_buffer_field(op->common.aml_opcode, obj_desc, 687 walk_state->operands[0], 688 walk_state->operands[1], 689 walk_state->operands[2], 690 walk_state->operands[3]); 691 } else { 692 /* All other, create_xxx_field opcodes */ 693 694 status = 695 acpi_ds_init_buffer_field(op->common.aml_opcode, obj_desc, 696 walk_state->operands[0], 697 walk_state->operands[1], NULL, 698 walk_state->operands[2]); 699 } 700 701 return_ACPI_STATUS(status); 702 } 703 704 /******************************************************************************* 705 * 706 * FUNCTION: acpi_ds_eval_region_operands 707 * 708 * PARAMETERS: walk_state - Current walk 709 * Op - A valid region Op object 710 * 711 * RETURN: Status 712 * 713 * DESCRIPTION: Get region address and length 714 * Called from acpi_ds_exec_end_op during op_region parse tree walk 715 * 716 ******************************************************************************/ 717 718 acpi_status 719 acpi_ds_eval_region_operands(struct acpi_walk_state *walk_state, 720 union acpi_parse_object *op) 721 { 722 acpi_status status; 723 union acpi_operand_object *obj_desc; 724 union acpi_operand_object *operand_desc; 725 struct acpi_namespace_node *node; 726 union acpi_parse_object *next_op; 727 728 ACPI_FUNCTION_TRACE_PTR(ds_eval_region_operands, op); 729 730 /* 731 * This is where we evaluate the address and length fields of the 732 * op_region declaration 733 */ 734 node = op->common.node; 735 736 /* next_op points to the op that holds the space_iD */ 737 738 next_op = op->common.value.arg; 739 740 /* next_op points to address op */ 741 742 next_op = next_op->common.next; 743 744 /* Evaluate/create the address and length operands */ 745 746 status = acpi_ds_create_operands(walk_state, next_op); 747 if (ACPI_FAILURE(status)) { 748 return_ACPI_STATUS(status); 749 } 750 751 /* Resolve the length and address operands to numbers */ 752 753 status = acpi_ex_resolve_operands(op->common.aml_opcode, 754 ACPI_WALK_OPERANDS, walk_state); 755 if (ACPI_FAILURE(status)) { 756 return_ACPI_STATUS(status); 757 } 758 759 obj_desc = acpi_ns_get_attached_object(node); 760 if (!obj_desc) { 761 return_ACPI_STATUS(AE_NOT_EXIST); 762 } 763 764 /* 765 * Get the length operand and save it 766 * (at Top of stack) 767 */ 768 operand_desc = walk_state->operands[walk_state->num_operands - 1]; 769 770 obj_desc->region.length = (u32) operand_desc->integer.value; 771 acpi_ut_remove_reference(operand_desc); 772 773 /* 774 * Get the address and save it 775 * (at top of stack - 1) 776 */ 777 operand_desc = walk_state->operands[walk_state->num_operands - 2]; 778 779 obj_desc->region.address = (acpi_physical_address) 780 operand_desc->integer.value; 781 acpi_ut_remove_reference(operand_desc); 782 783 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "RgnObj %p Addr %8.8X%8.8X Len %X\n", 784 obj_desc, 785 ACPI_FORMAT_NATIVE_UINT(obj_desc->region.address), 786 obj_desc->region.length)); 787 788 /* Now the address and length are valid for this opregion */ 789 790 obj_desc->region.flags |= AOPOBJ_DATA_VALID; 791 792 return_ACPI_STATUS(status); 793 } 794 795 /******************************************************************************* 796 * 797 * FUNCTION: acpi_ds_eval_table_region_operands 798 * 799 * PARAMETERS: walk_state - Current walk 800 * Op - A valid region Op object 801 * 802 * RETURN: Status 803 * 804 * DESCRIPTION: Get region address and length 805 * Called from acpi_ds_exec_end_op during data_table_region parse tree walk 806 * 807 ******************************************************************************/ 808 809 acpi_status 810 acpi_ds_eval_table_region_operands(struct acpi_walk_state *walk_state, 811 union acpi_parse_object *op) 812 { 813 acpi_status status; 814 union acpi_operand_object *obj_desc; 815 union acpi_operand_object **operand; 816 struct acpi_namespace_node *node; 817 union acpi_parse_object *next_op; 818 u32 table_index; 819 struct acpi_table_header *table; 820 821 ACPI_FUNCTION_TRACE_PTR(ds_eval_table_region_operands, op); 822 823 /* 824 * This is where we evaluate the signature_string and oem_iDString 825 * and oem_table_iDString of the data_table_region declaration 826 */ 827 node = op->common.node; 828 829 /* next_op points to signature_string op */ 830 831 next_op = op->common.value.arg; 832 833 /* 834 * Evaluate/create the signature_string and oem_iDString 835 * and oem_table_iDString operands 836 */ 837 status = acpi_ds_create_operands(walk_state, next_op); 838 if (ACPI_FAILURE(status)) { 839 return_ACPI_STATUS(status); 840 } 841 842 /* 843 * Resolve the signature_string and oem_iDString 844 * and oem_table_iDString operands 845 */ 846 status = acpi_ex_resolve_operands(op->common.aml_opcode, 847 ACPI_WALK_OPERANDS, walk_state); 848 if (ACPI_FAILURE(status)) { 849 return_ACPI_STATUS(status); 850 } 851 852 operand = &walk_state->operands[0]; 853 854 /* Find the ACPI table */ 855 856 status = acpi_tb_find_table(operand[0]->string.pointer, 857 operand[1]->string.pointer, 858 operand[2]->string.pointer, &table_index); 859 if (ACPI_FAILURE(status)) { 860 return_ACPI_STATUS(status); 861 } 862 863 acpi_ut_remove_reference(operand[0]); 864 acpi_ut_remove_reference(operand[1]); 865 acpi_ut_remove_reference(operand[2]); 866 867 status = acpi_get_table_by_index(table_index, &table); 868 if (ACPI_FAILURE(status)) { 869 return_ACPI_STATUS(status); 870 } 871 872 obj_desc = acpi_ns_get_attached_object(node); 873 if (!obj_desc) { 874 return_ACPI_STATUS(AE_NOT_EXIST); 875 } 876 877 obj_desc->region.address = 878 (acpi_physical_address) ACPI_TO_INTEGER(table); 879 obj_desc->region.length = table->length; 880 881 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "RgnObj %p Addr %8.8X%8.8X Len %X\n", 882 obj_desc, 883 ACPI_FORMAT_NATIVE_UINT(obj_desc->region.address), 884 obj_desc->region.length)); 885 886 /* Now the address and length are valid for this opregion */ 887 888 obj_desc->region.flags |= AOPOBJ_DATA_VALID; 889 890 return_ACPI_STATUS(status); 891 } 892 893 /******************************************************************************* 894 * 895 * FUNCTION: acpi_ds_eval_data_object_operands 896 * 897 * PARAMETERS: walk_state - Current walk 898 * Op - A valid data_object Op object 899 * obj_desc - data_object 900 * 901 * RETURN: Status 902 * 903 * DESCRIPTION: Get the operands and complete the following data object types: 904 * Buffer, Package. 905 * 906 ******************************************************************************/ 907 908 acpi_status 909 acpi_ds_eval_data_object_operands(struct acpi_walk_state *walk_state, 910 union acpi_parse_object *op, 911 union acpi_operand_object *obj_desc) 912 { 913 acpi_status status; 914 union acpi_operand_object *arg_desc; 915 u32 length; 916 917 ACPI_FUNCTION_TRACE(ds_eval_data_object_operands); 918 919 /* The first operand (for all of these data objects) is the length */ 920 921 /* 922 * Set proper index into operand stack for acpi_ds_obj_stack_push 923 * invoked inside acpi_ds_create_operand. 924 */ 925 walk_state->operand_index = walk_state->num_operands; 926 927 status = acpi_ds_create_operand(walk_state, op->common.value.arg, 1); 928 if (ACPI_FAILURE(status)) { 929 return_ACPI_STATUS(status); 930 } 931 932 status = acpi_ex_resolve_operands(walk_state->opcode, 933 &(walk_state-> 934 operands[walk_state->num_operands - 935 1]), walk_state); 936 if (ACPI_FAILURE(status)) { 937 return_ACPI_STATUS(status); 938 } 939 940 /* Extract length operand */ 941 942 arg_desc = walk_state->operands[walk_state->num_operands - 1]; 943 length = (u32) arg_desc->integer.value; 944 945 /* Cleanup for length operand */ 946 947 status = acpi_ds_obj_stack_pop(1, walk_state); 948 if (ACPI_FAILURE(status)) { 949 return_ACPI_STATUS(status); 950 } 951 952 acpi_ut_remove_reference(arg_desc); 953 954 /* 955 * Create the actual data object 956 */ 957 switch (op->common.aml_opcode) { 958 case AML_BUFFER_OP: 959 960 status = 961 acpi_ds_build_internal_buffer_obj(walk_state, op, length, 962 &obj_desc); 963 break; 964 965 case AML_PACKAGE_OP: 966 case AML_VAR_PACKAGE_OP: 967 968 status = 969 acpi_ds_build_internal_package_obj(walk_state, op, length, 970 &obj_desc); 971 break; 972 973 default: 974 return_ACPI_STATUS(AE_AML_BAD_OPCODE); 975 } 976 977 if (ACPI_SUCCESS(status)) { 978 /* 979 * Return the object in the walk_state, unless the parent is a package - 980 * in this case, the return object will be stored in the parse tree 981 * for the package. 982 */ 983 if ((!op->common.parent) || 984 ((op->common.parent->common.aml_opcode != AML_PACKAGE_OP) && 985 (op->common.parent->common.aml_opcode != 986 AML_VAR_PACKAGE_OP) 987 && (op->common.parent->common.aml_opcode != AML_NAME_OP))) { 988 walk_state->result_obj = obj_desc; 989 } 990 } 991 992 return_ACPI_STATUS(status); 993 } 994 995 /******************************************************************************* 996 * 997 * FUNCTION: acpi_ds_eval_bank_field_operands 998 * 999 * PARAMETERS: walk_state - Current walk 1000 * Op - A valid bank_field Op object 1001 * 1002 * RETURN: Status 1003 * 1004 * DESCRIPTION: Get bank_field bank_value 1005 * Called from acpi_ds_exec_end_op during bank_field parse tree walk 1006 * 1007 ******************************************************************************/ 1008 1009 acpi_status 1010 acpi_ds_eval_bank_field_operands(struct acpi_walk_state *walk_state, 1011 union acpi_parse_object *op) 1012 { 1013 acpi_status status; 1014 union acpi_operand_object *obj_desc; 1015 union acpi_operand_object *operand_desc; 1016 struct acpi_namespace_node *node; 1017 union acpi_parse_object *next_op; 1018 union acpi_parse_object *arg; 1019 1020 ACPI_FUNCTION_TRACE_PTR(ds_eval_bank_field_operands, op); 1021 1022 /* 1023 * This is where we evaluate the bank_value field of the 1024 * bank_field declaration 1025 */ 1026 1027 /* next_op points to the op that holds the Region */ 1028 1029 next_op = op->common.value.arg; 1030 1031 /* next_op points to the op that holds the Bank Register */ 1032 1033 next_op = next_op->common.next; 1034 1035 /* next_op points to the op that holds the Bank Value */ 1036 1037 next_op = next_op->common.next; 1038 1039 /* 1040 * Set proper index into operand stack for acpi_ds_obj_stack_push 1041 * invoked inside acpi_ds_create_operand. 1042 * 1043 * We use walk_state->Operands[0] to store the evaluated bank_value 1044 */ 1045 walk_state->operand_index = 0; 1046 1047 status = acpi_ds_create_operand(walk_state, next_op, 0); 1048 if (ACPI_FAILURE(status)) { 1049 return_ACPI_STATUS(status); 1050 } 1051 1052 status = acpi_ex_resolve_to_value(&walk_state->operands[0], walk_state); 1053 if (ACPI_FAILURE(status)) { 1054 return_ACPI_STATUS(status); 1055 } 1056 1057 ACPI_DUMP_OPERANDS(ACPI_WALK_OPERANDS, 1058 acpi_ps_get_opcode_name(op->common.aml_opcode), 1); 1059 /* 1060 * Get the bank_value operand and save it 1061 * (at Top of stack) 1062 */ 1063 operand_desc = walk_state->operands[0]; 1064 1065 /* Arg points to the start Bank Field */ 1066 1067 arg = acpi_ps_get_arg(op, 4); 1068 while (arg) { 1069 1070 /* Ignore OFFSET and ACCESSAS terms here */ 1071 1072 if (arg->common.aml_opcode == AML_INT_NAMEDFIELD_OP) { 1073 node = arg->common.node; 1074 1075 obj_desc = acpi_ns_get_attached_object(node); 1076 if (!obj_desc) { 1077 return_ACPI_STATUS(AE_NOT_EXIST); 1078 } 1079 1080 obj_desc->bank_field.value = 1081 (u32) operand_desc->integer.value; 1082 } 1083 1084 /* Move to next field in the list */ 1085 1086 arg = arg->common.next; 1087 } 1088 1089 acpi_ut_remove_reference(operand_desc); 1090 return_ACPI_STATUS(status); 1091 } 1092 1093 /******************************************************************************* 1094 * 1095 * FUNCTION: acpi_ds_exec_begin_control_op 1096 * 1097 * PARAMETERS: walk_list - The list that owns the walk stack 1098 * Op - The control Op 1099 * 1100 * RETURN: Status 1101 * 1102 * DESCRIPTION: Handles all control ops encountered during control method 1103 * execution. 1104 * 1105 ******************************************************************************/ 1106 1107 acpi_status 1108 acpi_ds_exec_begin_control_op(struct acpi_walk_state *walk_state, 1109 union acpi_parse_object *op) 1110 { 1111 acpi_status status = AE_OK; 1112 union acpi_generic_state *control_state; 1113 1114 ACPI_FUNCTION_NAME(ds_exec_begin_control_op); 1115 1116 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "Op=%p Opcode=%2.2X State=%p\n", op, 1117 op->common.aml_opcode, walk_state)); 1118 1119 switch (op->common.aml_opcode) { 1120 case AML_WHILE_OP: 1121 1122 /* 1123 * If this is an additional iteration of a while loop, continue. 1124 * There is no need to allocate a new control state. 1125 */ 1126 if (walk_state->control_state) { 1127 if (walk_state->control_state->control.aml_predicate_start 1128 == (walk_state->parser_state.aml - 1)) { 1129 1130 /* Reset the state to start-of-loop */ 1131 1132 walk_state->control_state->common.state = 1133 ACPI_CONTROL_CONDITIONAL_EXECUTING; 1134 break; 1135 } 1136 } 1137 1138 /*lint -fallthrough */ 1139 1140 case AML_IF_OP: 1141 1142 /* 1143 * IF/WHILE: Create a new control state to manage these 1144 * constructs. We need to manage these as a stack, in order 1145 * to handle nesting. 1146 */ 1147 control_state = acpi_ut_create_control_state(); 1148 if (!control_state) { 1149 status = AE_NO_MEMORY; 1150 break; 1151 } 1152 /* 1153 * Save a pointer to the predicate for multiple executions 1154 * of a loop 1155 */ 1156 control_state->control.aml_predicate_start = 1157 walk_state->parser_state.aml - 1; 1158 control_state->control.package_end = 1159 walk_state->parser_state.pkg_end; 1160 control_state->control.opcode = op->common.aml_opcode; 1161 1162 /* Push the control state on this walk's control stack */ 1163 1164 acpi_ut_push_generic_state(&walk_state->control_state, 1165 control_state); 1166 break; 1167 1168 case AML_ELSE_OP: 1169 1170 /* Predicate is in the state object */ 1171 /* If predicate is true, the IF was executed, ignore ELSE part */ 1172 1173 if (walk_state->last_predicate) { 1174 status = AE_CTRL_TRUE; 1175 } 1176 1177 break; 1178 1179 case AML_RETURN_OP: 1180 1181 break; 1182 1183 default: 1184 break; 1185 } 1186 1187 return (status); 1188 } 1189 1190 /******************************************************************************* 1191 * 1192 * FUNCTION: acpi_ds_exec_end_control_op 1193 * 1194 * PARAMETERS: walk_list - The list that owns the walk stack 1195 * Op - The control Op 1196 * 1197 * RETURN: Status 1198 * 1199 * DESCRIPTION: Handles all control ops encountered during control method 1200 * execution. 1201 * 1202 ******************************************************************************/ 1203 1204 acpi_status 1205 acpi_ds_exec_end_control_op(struct acpi_walk_state * walk_state, 1206 union acpi_parse_object * op) 1207 { 1208 acpi_status status = AE_OK; 1209 union acpi_generic_state *control_state; 1210 1211 ACPI_FUNCTION_NAME(ds_exec_end_control_op); 1212 1213 switch (op->common.aml_opcode) { 1214 case AML_IF_OP: 1215 1216 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "[IF_OP] Op=%p\n", op)); 1217 1218 /* 1219 * Save the result of the predicate in case there is an 1220 * ELSE to come 1221 */ 1222 walk_state->last_predicate = 1223 (u8) walk_state->control_state->common.value; 1224 1225 /* 1226 * Pop the control state that was created at the start 1227 * of the IF and free it 1228 */ 1229 control_state = 1230 acpi_ut_pop_generic_state(&walk_state->control_state); 1231 acpi_ut_delete_generic_state(control_state); 1232 break; 1233 1234 case AML_ELSE_OP: 1235 1236 break; 1237 1238 case AML_WHILE_OP: 1239 1240 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, "[WHILE_OP] Op=%p\n", op)); 1241 1242 control_state = walk_state->control_state; 1243 if (control_state->common.value) { 1244 1245 /* Predicate was true, the body of the loop was just executed */ 1246 1247 /* 1248 * This loop counter mechanism allows the interpreter to escape 1249 * possibly infinite loops. This can occur in poorly written AML 1250 * when the hardware does not respond within a while loop and the 1251 * loop does not implement a timeout. 1252 */ 1253 control_state->control.loop_count++; 1254 if (control_state->control.loop_count > 1255 ACPI_MAX_LOOP_ITERATIONS) { 1256 status = AE_AML_INFINITE_LOOP; 1257 break; 1258 } 1259 1260 /* 1261 * Go back and evaluate the predicate and maybe execute the loop 1262 * another time 1263 */ 1264 status = AE_CTRL_PENDING; 1265 walk_state->aml_last_while = 1266 control_state->control.aml_predicate_start; 1267 break; 1268 } 1269 1270 /* Predicate was false, terminate this while loop */ 1271 1272 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, 1273 "[WHILE_OP] termination! Op=%p\n", op)); 1274 1275 /* Pop this control state and free it */ 1276 1277 control_state = 1278 acpi_ut_pop_generic_state(&walk_state->control_state); 1279 acpi_ut_delete_generic_state(control_state); 1280 break; 1281 1282 case AML_RETURN_OP: 1283 1284 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, 1285 "[RETURN_OP] Op=%p Arg=%p\n", op, 1286 op->common.value.arg)); 1287 1288 /* 1289 * One optional operand -- the return value 1290 * It can be either an immediate operand or a result that 1291 * has been bubbled up the tree 1292 */ 1293 if (op->common.value.arg) { 1294 1295 /* Since we have a real Return(), delete any implicit return */ 1296 1297 acpi_ds_clear_implicit_return(walk_state); 1298 1299 /* Return statement has an immediate operand */ 1300 1301 status = 1302 acpi_ds_create_operands(walk_state, 1303 op->common.value.arg); 1304 if (ACPI_FAILURE(status)) { 1305 return (status); 1306 } 1307 1308 /* 1309 * If value being returned is a Reference (such as 1310 * an arg or local), resolve it now because it may 1311 * cease to exist at the end of the method. 1312 */ 1313 status = 1314 acpi_ex_resolve_to_value(&walk_state->operands[0], 1315 walk_state); 1316 if (ACPI_FAILURE(status)) { 1317 return (status); 1318 } 1319 1320 /* 1321 * Get the return value and save as the last result 1322 * value. This is the only place where walk_state->return_desc 1323 * is set to anything other than zero! 1324 */ 1325 walk_state->return_desc = walk_state->operands[0]; 1326 } else if (walk_state->result_count) { 1327 1328 /* Since we have a real Return(), delete any implicit return */ 1329 1330 acpi_ds_clear_implicit_return(walk_state); 1331 1332 /* 1333 * The return value has come from a previous calculation. 1334 * 1335 * If value being returned is a Reference (such as 1336 * an arg or local), resolve it now because it may 1337 * cease to exist at the end of the method. 1338 * 1339 * Allow references created by the Index operator to return unchanged. 1340 */ 1341 if ((ACPI_GET_DESCRIPTOR_TYPE 1342 (walk_state->results->results.obj_desc[0]) == 1343 ACPI_DESC_TYPE_OPERAND) 1344 && ((walk_state->results->results.obj_desc[0])-> 1345 common.type == ACPI_TYPE_LOCAL_REFERENCE) 1346 && ((walk_state->results->results.obj_desc[0])-> 1347 reference.class != ACPI_REFCLASS_INDEX)) { 1348 status = 1349 acpi_ex_resolve_to_value(&walk_state-> 1350 results->results. 1351 obj_desc[0], 1352 walk_state); 1353 if (ACPI_FAILURE(status)) { 1354 return (status); 1355 } 1356 } 1357 1358 walk_state->return_desc = 1359 walk_state->results->results.obj_desc[0]; 1360 } else { 1361 /* No return operand */ 1362 1363 if (walk_state->num_operands) { 1364 acpi_ut_remove_reference(walk_state-> 1365 operands[0]); 1366 } 1367 1368 walk_state->operands[0] = NULL; 1369 walk_state->num_operands = 0; 1370 walk_state->return_desc = NULL; 1371 } 1372 1373 ACPI_DEBUG_PRINT((ACPI_DB_DISPATCH, 1374 "Completed RETURN_OP State=%p, RetVal=%p\n", 1375 walk_state, walk_state->return_desc)); 1376 1377 /* End the control method execution right now */ 1378 1379 status = AE_CTRL_TERMINATE; 1380 break; 1381 1382 case AML_NOOP_OP: 1383 1384 /* Just do nothing! */ 1385 break; 1386 1387 case AML_BREAK_POINT_OP: 1388 1389 /* Call up to the OS service layer to handle this */ 1390 1391 status = 1392 acpi_os_signal(ACPI_SIGNAL_BREAKPOINT, 1393 "Executed AML Breakpoint opcode"); 1394 1395 /* If and when it returns, all done. */ 1396 1397 break; 1398 1399 case AML_BREAK_OP: 1400 case AML_CONTINUE_OP: /* ACPI 2.0 */ 1401 1402 /* Pop and delete control states until we find a while */ 1403 1404 while (walk_state->control_state && 1405 (walk_state->control_state->control.opcode != 1406 AML_WHILE_OP)) { 1407 control_state = 1408 acpi_ut_pop_generic_state(&walk_state-> 1409 control_state); 1410 acpi_ut_delete_generic_state(control_state); 1411 } 1412 1413 /* No while found? */ 1414 1415 if (!walk_state->control_state) { 1416 return (AE_AML_NO_WHILE); 1417 } 1418 1419 /* Was: walk_state->aml_last_while = walk_state->control_state->Control.aml_predicate_start; */ 1420 1421 walk_state->aml_last_while = 1422 walk_state->control_state->control.package_end; 1423 1424 /* Return status depending on opcode */ 1425 1426 if (op->common.aml_opcode == AML_BREAK_OP) { 1427 status = AE_CTRL_BREAK; 1428 } else { 1429 status = AE_CTRL_CONTINUE; 1430 } 1431 break; 1432 1433 default: 1434 1435 ACPI_ERROR((AE_INFO, "Unknown control opcode=%X Op=%p", 1436 op->common.aml_opcode, op)); 1437 1438 status = AE_AML_BAD_OPCODE; 1439 break; 1440 } 1441 1442 return (status); 1443 } 1444