Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
at v2.6.13 1186 lines 32 kB view raw
1/****************************************************************************** 2 * 3 * Module Name: dsopcode - Dispatcher Op Region support and handling of 4 * "control" opcodes 5 * 6 *****************************************************************************/ 7 8/* 9 * Copyright (C) 2000 - 2005, R. Byron Moore 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 46#include <acpi/acpi.h> 47#include <acpi/acparser.h> 48#include <acpi/amlcode.h> 49#include <acpi/acdispat.h> 50#include <acpi/acinterp.h> 51#include <acpi/acnamesp.h> 52#include <acpi/acevents.h> 53 54#define _COMPONENT ACPI_DISPATCHER 55 ACPI_MODULE_NAME ("dsopcode") 56 57/* Local prototypes */ 58 59static acpi_status 60acpi_ds_execute_arguments ( 61 struct acpi_namespace_node *node, 62 struct acpi_namespace_node *scope_node, 63 u32 aml_length, 64 u8 *aml_start); 65 66static acpi_status 67acpi_ds_init_buffer_field ( 68 u16 aml_opcode, 69 union acpi_operand_object *obj_desc, 70 union acpi_operand_object *buffer_desc, 71 union acpi_operand_object *offset_desc, 72 union acpi_operand_object *length_desc, 73 union acpi_operand_object *result_desc); 74 75 76/******************************************************************************* 77 * 78 * FUNCTION: acpi_ds_execute_arguments 79 * 80 * PARAMETERS: Node - Object NS node 81 * scope_node - Parent NS node 82 * aml_length - Length of executable AML 83 * aml_start - Pointer to the AML 84 * 85 * RETURN: Status. 86 * 87 * DESCRIPTION: Late (deferred) execution of region or field arguments 88 * 89 ******************************************************************************/ 90 91static acpi_status 92acpi_ds_execute_arguments ( 93 struct acpi_namespace_node *node, 94 struct acpi_namespace_node *scope_node, 95 u32 aml_length, 96 u8 *aml_start) 97{ 98 acpi_status status; 99 union acpi_parse_object *op; 100 struct acpi_walk_state *walk_state; 101 102 103 ACPI_FUNCTION_TRACE ("ds_execute_arguments"); 104 105 106 /* 107 * Allocate a new parser op to be the root of the parsed tree 108 */ 109 op = acpi_ps_alloc_op (AML_INT_EVAL_SUBTREE_OP); 110 if (!op) { 111 return_ACPI_STATUS (AE_NO_MEMORY); 112 } 113 114 /* Save the Node for use in acpi_ps_parse_aml */ 115 116 op->common.node = scope_node; 117 118 /* Create and initialize a new parser state */ 119 120 walk_state = acpi_ds_create_walk_state (0, NULL, NULL, NULL); 121 if (!walk_state) { 122 return_ACPI_STATUS (AE_NO_MEMORY); 123 } 124 125 status = acpi_ds_init_aml_walk (walk_state, op, NULL, aml_start, 126 aml_length, NULL, 1); 127 if (ACPI_FAILURE (status)) { 128 acpi_ds_delete_walk_state (walk_state); 129 return_ACPI_STATUS (status); 130 } 131 132 /* Mark this parse as a deferred opcode */ 133 134 walk_state->parse_flags = ACPI_PARSE_DEFERRED_OP; 135 walk_state->deferred_node = node; 136 137 /* Pass1: Parse the entire declaration */ 138 139 status = acpi_ps_parse_aml (walk_state); 140 if (ACPI_FAILURE (status)) { 141 acpi_ps_delete_parse_tree (op); 142 return_ACPI_STATUS (status); 143 } 144 145 /* Get and init the Op created above */ 146 147 op->common.node = node; 148 acpi_ps_delete_parse_tree (op); 149 150 /* Evaluate the deferred arguments */ 151 152 op = acpi_ps_alloc_op (AML_INT_EVAL_SUBTREE_OP); 153 if (!op) { 154 return_ACPI_STATUS (AE_NO_MEMORY); 155 } 156 157 op->common.node = scope_node; 158 159 /* Create and initialize a new parser state */ 160 161 walk_state = acpi_ds_create_walk_state (0, NULL, NULL, NULL); 162 if (!walk_state) { 163 return_ACPI_STATUS (AE_NO_MEMORY); 164 } 165 166 /* Execute the opcode and arguments */ 167 168 status = acpi_ds_init_aml_walk (walk_state, op, NULL, aml_start, 169 aml_length, NULL, 3); 170 if (ACPI_FAILURE (status)) { 171 acpi_ds_delete_walk_state (walk_state); 172 return_ACPI_STATUS (status); 173 } 174 175 /* Mark this execution as a deferred opcode */ 176 177 walk_state->deferred_node = node; 178 status = acpi_ps_parse_aml (walk_state); 179 acpi_ps_delete_parse_tree (op); 180 return_ACPI_STATUS (status); 181} 182 183 184/******************************************************************************* 185 * 186 * FUNCTION: acpi_ds_get_buffer_field_arguments 187 * 188 * PARAMETERS: obj_desc - A valid buffer_field object 189 * 190 * RETURN: Status. 191 * 192 * DESCRIPTION: Get buffer_field Buffer and Index. This implements the late 193 * evaluation of these field attributes. 194 * 195 ******************************************************************************/ 196 197acpi_status 198acpi_ds_get_buffer_field_arguments ( 199 union acpi_operand_object *obj_desc) 200{ 201 union acpi_operand_object *extra_desc; 202 struct acpi_namespace_node *node; 203 acpi_status status; 204 205 206 ACPI_FUNCTION_TRACE_PTR ("ds_get_buffer_field_arguments", obj_desc); 207 208 209 if (obj_desc->common.flags & AOPOBJ_DATA_VALID) { 210 return_ACPI_STATUS (AE_OK); 211 } 212 213 /* Get the AML pointer (method object) and buffer_field node */ 214 215 extra_desc = acpi_ns_get_secondary_object (obj_desc); 216 node = obj_desc->buffer_field.node; 217 218 ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname (ACPI_TYPE_BUFFER_FIELD, node, NULL)); 219 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[%4.4s] buffer_field Arg Init\n", 220 acpi_ut_get_node_name (node))); 221 222 /* Execute the AML code for the term_arg arguments */ 223 224 status = acpi_ds_execute_arguments (node, acpi_ns_get_parent_node (node), 225 extra_desc->extra.aml_length, extra_desc->extra.aml_start); 226 return_ACPI_STATUS (status); 227} 228 229 230/******************************************************************************* 231 * 232 * FUNCTION: acpi_ds_get_buffer_arguments 233 * 234 * PARAMETERS: obj_desc - A valid Buffer object 235 * 236 * RETURN: Status. 237 * 238 * DESCRIPTION: Get Buffer length and initializer byte list. This implements 239 * the late evaluation of these attributes. 240 * 241 ******************************************************************************/ 242 243acpi_status 244acpi_ds_get_buffer_arguments ( 245 union acpi_operand_object *obj_desc) 246{ 247 struct acpi_namespace_node *node; 248 acpi_status status; 249 250 251 ACPI_FUNCTION_TRACE_PTR ("ds_get_buffer_arguments", obj_desc); 252 253 254 if (obj_desc->common.flags & AOPOBJ_DATA_VALID) { 255 return_ACPI_STATUS (AE_OK); 256 } 257 258 /* Get the Buffer node */ 259 260 node = obj_desc->buffer.node; 261 if (!node) { 262 ACPI_REPORT_ERROR (( 263 "No pointer back to NS node in buffer obj %p\n", obj_desc)); 264 return_ACPI_STATUS (AE_AML_INTERNAL); 265 } 266 267 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Buffer Arg Init\n")); 268 269 /* Execute the AML code for the term_arg arguments */ 270 271 status = acpi_ds_execute_arguments (node, node, 272 obj_desc->buffer.aml_length, obj_desc->buffer.aml_start); 273 return_ACPI_STATUS (status); 274} 275 276 277/******************************************************************************* 278 * 279 * FUNCTION: acpi_ds_get_package_arguments 280 * 281 * PARAMETERS: obj_desc - A valid Package object 282 * 283 * RETURN: Status. 284 * 285 * DESCRIPTION: Get Package length and initializer byte list. This implements 286 * the late evaluation of these attributes. 287 * 288 ******************************************************************************/ 289 290acpi_status 291acpi_ds_get_package_arguments ( 292 union acpi_operand_object *obj_desc) 293{ 294 struct acpi_namespace_node *node; 295 acpi_status status; 296 297 298 ACPI_FUNCTION_TRACE_PTR ("ds_get_package_arguments", obj_desc); 299 300 301 if (obj_desc->common.flags & AOPOBJ_DATA_VALID) { 302 return_ACPI_STATUS (AE_OK); 303 } 304 305 /* Get the Package node */ 306 307 node = obj_desc->package.node; 308 if (!node) { 309 ACPI_REPORT_ERROR (( 310 "No pointer back to NS node in package %p\n", obj_desc)); 311 return_ACPI_STATUS (AE_AML_INTERNAL); 312 } 313 314 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Package Arg Init\n")); 315 316 /* Execute the AML code for the term_arg arguments */ 317 318 status = acpi_ds_execute_arguments (node, node, 319 obj_desc->package.aml_length, obj_desc->package.aml_start); 320 return_ACPI_STATUS (status); 321} 322 323 324/***************************************************************************** 325 * 326 * FUNCTION: acpi_ds_get_region_arguments 327 * 328 * PARAMETERS: obj_desc - A valid region object 329 * 330 * RETURN: Status. 331 * 332 * DESCRIPTION: Get region address and length. This implements the late 333 * evaluation of these region attributes. 334 * 335 ****************************************************************************/ 336 337acpi_status 338acpi_ds_get_region_arguments ( 339 union acpi_operand_object *obj_desc) 340{ 341 struct acpi_namespace_node *node; 342 acpi_status status; 343 union acpi_operand_object *extra_desc; 344 345 346 ACPI_FUNCTION_TRACE_PTR ("ds_get_region_arguments", obj_desc); 347 348 349 if (obj_desc->region.flags & AOPOBJ_DATA_VALID) { 350 return_ACPI_STATUS (AE_OK); 351 } 352 353 extra_desc = acpi_ns_get_secondary_object (obj_desc); 354 if (!extra_desc) { 355 return_ACPI_STATUS (AE_NOT_EXIST); 356 } 357 358 /* Get the Region node */ 359 360 node = obj_desc->region.node; 361 362 ACPI_DEBUG_EXEC (acpi_ut_display_init_pathname (ACPI_TYPE_REGION, node, NULL)); 363 364 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[%4.4s] op_region Arg Init at AML %p\n", 365 acpi_ut_get_node_name (node), extra_desc->extra.aml_start)); 366 367 /* Execute the argument AML */ 368 369 status = acpi_ds_execute_arguments (node, acpi_ns_get_parent_node (node), 370 extra_desc->extra.aml_length, extra_desc->extra.aml_start); 371 return_ACPI_STATUS (status); 372} 373 374 375/******************************************************************************* 376 * 377 * FUNCTION: acpi_ds_initialize_region 378 * 379 * PARAMETERS: obj_handle - Region namespace node 380 * 381 * RETURN: Status 382 * 383 * DESCRIPTION: Front end to ev_initialize_region 384 * 385 ******************************************************************************/ 386 387acpi_status 388acpi_ds_initialize_region ( 389 acpi_handle obj_handle) 390{ 391 union acpi_operand_object *obj_desc; 392 acpi_status status; 393 394 395 obj_desc = acpi_ns_get_attached_object (obj_handle); 396 397 /* Namespace is NOT locked */ 398 399 status = acpi_ev_initialize_region (obj_desc, FALSE); 400 return (status); 401} 402 403 404/******************************************************************************* 405 * 406 * FUNCTION: acpi_ds_init_buffer_field 407 * 408 * PARAMETERS: aml_opcode - create_xxx_field 409 * obj_desc - buffer_field object 410 * buffer_desc - Host Buffer 411 * offset_desc - Offset into buffer 412 * length_desc - Length of field (CREATE_FIELD_OP only) 413 * result_desc - Where to store the result 414 * 415 * RETURN: Status 416 * 417 * DESCRIPTION: Perform actual initialization of a buffer field 418 * 419 ******************************************************************************/ 420 421static acpi_status 422acpi_ds_init_buffer_field ( 423 u16 aml_opcode, 424 union acpi_operand_object *obj_desc, 425 union acpi_operand_object *buffer_desc, 426 union acpi_operand_object *offset_desc, 427 union acpi_operand_object *length_desc, 428 union acpi_operand_object *result_desc) 429{ 430 u32 offset; 431 u32 bit_offset; 432 u32 bit_count; 433 u8 field_flags; 434 acpi_status status; 435 436 437 ACPI_FUNCTION_TRACE_PTR ("ds_init_buffer_field", obj_desc); 438 439 440 /* Host object must be a Buffer */ 441 442 if (ACPI_GET_OBJECT_TYPE (buffer_desc) != ACPI_TYPE_BUFFER) { 443 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, 444 "Target of Create Field is not a Buffer object - %s\n", 445 acpi_ut_get_object_type_name (buffer_desc))); 446 447 status = AE_AML_OPERAND_TYPE; 448 goto cleanup; 449 } 450 451 /* 452 * The last parameter to all of these opcodes (result_desc) started 453 * out as a name_string, and should therefore now be a NS node 454 * after resolution in acpi_ex_resolve_operands(). 455 */ 456 if (ACPI_GET_DESCRIPTOR_TYPE (result_desc) != ACPI_DESC_TYPE_NAMED) { 457 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, 458 "(%s) destination not a NS Node [%s]\n", 459 acpi_ps_get_opcode_name (aml_opcode), 460 acpi_ut_get_descriptor_name (result_desc))); 461 462 status = AE_AML_OPERAND_TYPE; 463 goto cleanup; 464 } 465 466 offset = (u32) offset_desc->integer.value; 467 468 /* 469 * Setup the Bit offsets and counts, according to the opcode 470 */ 471 switch (aml_opcode) { 472 case AML_CREATE_FIELD_OP: 473 474 /* Offset is in bits, count is in bits */ 475 476 field_flags = AML_FIELD_ACCESS_BYTE; 477 bit_offset = offset; 478 bit_count = (u32) length_desc->integer.value; 479 480 /* Must have a valid (>0) bit count */ 481 482 if (bit_count == 0) { 483 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, 484 "Attempt to create_field of length 0\n")); 485 status = AE_AML_OPERAND_VALUE; 486 goto cleanup; 487 } 488 break; 489 490 case AML_CREATE_BIT_FIELD_OP: 491 492 /* Offset is in bits, Field is one bit */ 493 494 bit_offset = offset; 495 bit_count = 1; 496 field_flags = AML_FIELD_ACCESS_BYTE; 497 break; 498 499 case AML_CREATE_BYTE_FIELD_OP: 500 501 /* Offset is in bytes, field is one byte */ 502 503 bit_offset = 8 * offset; 504 bit_count = 8; 505 field_flags = AML_FIELD_ACCESS_BYTE; 506 break; 507 508 case AML_CREATE_WORD_FIELD_OP: 509 510 /* Offset is in bytes, field is one word */ 511 512 bit_offset = 8 * offset; 513 bit_count = 16; 514 field_flags = AML_FIELD_ACCESS_WORD; 515 break; 516 517 case AML_CREATE_DWORD_FIELD_OP: 518 519 /* Offset is in bytes, field is one dword */ 520 521 bit_offset = 8 * offset; 522 bit_count = 32; 523 field_flags = AML_FIELD_ACCESS_DWORD; 524 break; 525 526 case AML_CREATE_QWORD_FIELD_OP: 527 528 /* Offset is in bytes, field is one qword */ 529 530 bit_offset = 8 * offset; 531 bit_count = 64; 532 field_flags = AML_FIELD_ACCESS_QWORD; 533 break; 534 535 default: 536 537 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, 538 "Unknown field creation opcode %02x\n", 539 aml_opcode)); 540 status = AE_AML_BAD_OPCODE; 541 goto cleanup; 542 } 543 544 /* Entire field must fit within the current length of the buffer */ 545 546 if ((bit_offset + bit_count) > 547 (8 * (u32) buffer_desc->buffer.length)) { 548 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, 549 "Field [%4.4s] size %d exceeds Buffer [%4.4s] size %d (bits)\n", 550 acpi_ut_get_node_name (result_desc), 551 bit_offset + bit_count, 552 acpi_ut_get_node_name (buffer_desc->buffer.node), 553 8 * (u32) buffer_desc->buffer.length)); 554 status = AE_AML_BUFFER_LIMIT; 555 goto cleanup; 556 } 557 558 /* 559 * Initialize areas of the field object that are common to all fields 560 * For field_flags, use LOCK_RULE = 0 (NO_LOCK), 561 * UPDATE_RULE = 0 (UPDATE_PRESERVE) 562 */ 563 status = acpi_ex_prep_common_field_object (obj_desc, field_flags, 0, 564 bit_offset, bit_count); 565 if (ACPI_FAILURE (status)) { 566 goto cleanup; 567 } 568 569 obj_desc->buffer_field.buffer_obj = buffer_desc; 570 571 /* Reference count for buffer_desc inherits obj_desc count */ 572 573 buffer_desc->common.reference_count = (u16) 574 (buffer_desc->common.reference_count + obj_desc->common.reference_count); 575 576 577cleanup: 578 579 /* Always delete the operands */ 580 581 acpi_ut_remove_reference (offset_desc); 582 acpi_ut_remove_reference (buffer_desc); 583 584 if (aml_opcode == AML_CREATE_FIELD_OP) { 585 acpi_ut_remove_reference (length_desc); 586 } 587 588 /* On failure, delete the result descriptor */ 589 590 if (ACPI_FAILURE (status)) { 591 acpi_ut_remove_reference (result_desc); /* Result descriptor */ 592 } 593 else { 594 /* Now the address and length are valid for this buffer_field */ 595 596 obj_desc->buffer_field.flags |= AOPOBJ_DATA_VALID; 597 } 598 599 return_ACPI_STATUS (status); 600} 601 602 603/******************************************************************************* 604 * 605 * FUNCTION: acpi_ds_eval_buffer_field_operands 606 * 607 * PARAMETERS: walk_state - Current walk 608 * Op - A valid buffer_field Op object 609 * 610 * RETURN: Status 611 * 612 * DESCRIPTION: Get buffer_field Buffer and Index 613 * Called from acpi_ds_exec_end_op during buffer_field parse tree walk 614 * 615 ******************************************************************************/ 616 617acpi_status 618acpi_ds_eval_buffer_field_operands ( 619 struct acpi_walk_state *walk_state, 620 union acpi_parse_object *op) 621{ 622 acpi_status status; 623 union acpi_operand_object *obj_desc; 624 struct acpi_namespace_node *node; 625 union acpi_parse_object *next_op; 626 627 628 ACPI_FUNCTION_TRACE_PTR ("ds_eval_buffer_field_operands", op); 629 630 631 /* 632 * This is where we evaluate the address and length fields of the 633 * create_xxx_field declaration 634 */ 635 node = op->common.node; 636 637 /* next_op points to the op that holds the Buffer */ 638 639 next_op = op->common.value.arg; 640 641 /* Evaluate/create the address and length operands */ 642 643 status = acpi_ds_create_operands (walk_state, next_op); 644 if (ACPI_FAILURE (status)) { 645 return_ACPI_STATUS (status); 646 } 647 648 obj_desc = acpi_ns_get_attached_object (node); 649 if (!obj_desc) { 650 return_ACPI_STATUS (AE_NOT_EXIST); 651 } 652 653 /* Resolve the operands */ 654 655 status = acpi_ex_resolve_operands (op->common.aml_opcode, 656 ACPI_WALK_OPERANDS, walk_state); 657 658 ACPI_DUMP_OPERANDS (ACPI_WALK_OPERANDS, ACPI_IMODE_EXECUTE, 659 acpi_ps_get_opcode_name (op->common.aml_opcode), 660 walk_state->num_operands, "after acpi_ex_resolve_operands"); 661 662 if (ACPI_FAILURE (status)) { 663 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "(%s) bad operand(s) (%X)\n", 664 acpi_ps_get_opcode_name (op->common.aml_opcode), status)); 665 666 return_ACPI_STATUS (status); 667 } 668 669 /* Initialize the Buffer Field */ 670 671 if (op->common.aml_opcode == AML_CREATE_FIELD_OP) { 672 /* NOTE: Slightly different operands for this opcode */ 673 674 status = acpi_ds_init_buffer_field (op->common.aml_opcode, obj_desc, 675 walk_state->operands[0], walk_state->operands[1], 676 walk_state->operands[2], walk_state->operands[3]); 677 } 678 else { 679 /* All other, create_xxx_field opcodes */ 680 681 status = acpi_ds_init_buffer_field (op->common.aml_opcode, obj_desc, 682 walk_state->operands[0], walk_state->operands[1], 683 NULL, walk_state->operands[2]); 684 } 685 686 return_ACPI_STATUS (status); 687} 688 689 690/******************************************************************************* 691 * 692 * FUNCTION: acpi_ds_eval_region_operands 693 * 694 * PARAMETERS: walk_state - Current walk 695 * Op - A valid region Op object 696 * 697 * RETURN: Status 698 * 699 * DESCRIPTION: Get region address and length 700 * Called from acpi_ds_exec_end_op during op_region parse tree walk 701 * 702 ******************************************************************************/ 703 704acpi_status 705acpi_ds_eval_region_operands ( 706 struct acpi_walk_state *walk_state, 707 union acpi_parse_object *op) 708{ 709 acpi_status status; 710 union acpi_operand_object *obj_desc; 711 union acpi_operand_object *operand_desc; 712 struct acpi_namespace_node *node; 713 union acpi_parse_object *next_op; 714 715 716 ACPI_FUNCTION_TRACE_PTR ("ds_eval_region_operands", op); 717 718 719 /* 720 * This is where we evaluate the address and length fields of the 721 * op_region declaration 722 */ 723 node = op->common.node; 724 725 /* next_op points to the op that holds the space_iD */ 726 727 next_op = op->common.value.arg; 728 729 /* next_op points to address op */ 730 731 next_op = next_op->common.next; 732 733 /* Evaluate/create the address and length operands */ 734 735 status = acpi_ds_create_operands (walk_state, next_op); 736 if (ACPI_FAILURE (status)) { 737 return_ACPI_STATUS (status); 738 } 739 740 /* Resolve the length and address operands to numbers */ 741 742 status = acpi_ex_resolve_operands (op->common.aml_opcode, 743 ACPI_WALK_OPERANDS, walk_state); 744 if (ACPI_FAILURE (status)) { 745 return_ACPI_STATUS (status); 746 } 747 748 ACPI_DUMP_OPERANDS (ACPI_WALK_OPERANDS, ACPI_IMODE_EXECUTE, 749 acpi_ps_get_opcode_name (op->common.aml_opcode), 750 1, "after acpi_ex_resolve_operands"); 751 752 obj_desc = acpi_ns_get_attached_object (node); 753 if (!obj_desc) { 754 return_ACPI_STATUS (AE_NOT_EXIST); 755 } 756 757 /* 758 * Get the length operand and save it 759 * (at Top of stack) 760 */ 761 operand_desc = walk_state->operands[walk_state->num_operands - 1]; 762 763 obj_desc->region.length = (u32) operand_desc->integer.value; 764 acpi_ut_remove_reference (operand_desc); 765 766 /* 767 * Get the address and save it 768 * (at top of stack - 1) 769 */ 770 operand_desc = walk_state->operands[walk_state->num_operands - 2]; 771 772 obj_desc->region.address = (acpi_physical_address) 773 operand_desc->integer.value; 774 acpi_ut_remove_reference (operand_desc); 775 776 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "rgn_obj %p Addr %8.8X%8.8X Len %X\n", 777 obj_desc, 778 ACPI_FORMAT_UINT64 (obj_desc->region.address), 779 obj_desc->region.length)); 780 781 /* Now the address and length are valid for this opregion */ 782 783 obj_desc->region.flags |= AOPOBJ_DATA_VALID; 784 785 return_ACPI_STATUS (status); 786} 787 788 789/******************************************************************************* 790 * 791 * FUNCTION: acpi_ds_eval_data_object_operands 792 * 793 * PARAMETERS: walk_state - Current walk 794 * Op - A valid data_object Op object 795 * obj_desc - data_object 796 * 797 * RETURN: Status 798 * 799 * DESCRIPTION: Get the operands and complete the following data object types: 800 * Buffer, Package. 801 * 802 ******************************************************************************/ 803 804acpi_status 805acpi_ds_eval_data_object_operands ( 806 struct acpi_walk_state *walk_state, 807 union acpi_parse_object *op, 808 union acpi_operand_object *obj_desc) 809{ 810 acpi_status status; 811 union acpi_operand_object *arg_desc; 812 u32 length; 813 814 815 ACPI_FUNCTION_TRACE ("ds_eval_data_object_operands"); 816 817 818 /* The first operand (for all of these data objects) is the length */ 819 820 status = acpi_ds_create_operand (walk_state, op->common.value.arg, 1); 821 if (ACPI_FAILURE (status)) { 822 return_ACPI_STATUS (status); 823 } 824 825 status = acpi_ex_resolve_operands (walk_state->opcode, 826 &(walk_state->operands [walk_state->num_operands -1]), 827 walk_state); 828 if (ACPI_FAILURE (status)) { 829 return_ACPI_STATUS (status); 830 } 831 832 /* Extract length operand */ 833 834 arg_desc = walk_state->operands [walk_state->num_operands - 1]; 835 length = (u32) arg_desc->integer.value; 836 837 /* Cleanup for length operand */ 838 839 status = acpi_ds_obj_stack_pop (1, walk_state); 840 if (ACPI_FAILURE (status)) { 841 return_ACPI_STATUS (status); 842 } 843 844 acpi_ut_remove_reference (arg_desc); 845 846 /* 847 * Create the actual data object 848 */ 849 switch (op->common.aml_opcode) { 850 case AML_BUFFER_OP: 851 852 status = acpi_ds_build_internal_buffer_obj (walk_state, op, length, &obj_desc); 853 break; 854 855 case AML_PACKAGE_OP: 856 case AML_VAR_PACKAGE_OP: 857 858 status = acpi_ds_build_internal_package_obj (walk_state, op, length, &obj_desc); 859 break; 860 861 default: 862 return_ACPI_STATUS (AE_AML_BAD_OPCODE); 863 } 864 865 if (ACPI_SUCCESS (status)) { 866 /* 867 * Return the object in the walk_state, unless the parent is a package - 868 * in this case, the return object will be stored in the parse tree 869 * for the package. 870 */ 871 if ((!op->common.parent) || 872 ((op->common.parent->common.aml_opcode != AML_PACKAGE_OP) && 873 (op->common.parent->common.aml_opcode != AML_VAR_PACKAGE_OP) && 874 (op->common.parent->common.aml_opcode != AML_NAME_OP))) { 875 walk_state->result_obj = obj_desc; 876 } 877 } 878 879 return_ACPI_STATUS (status); 880} 881 882 883/******************************************************************************* 884 * 885 * FUNCTION: acpi_ds_exec_begin_control_op 886 * 887 * PARAMETERS: walk_list - The list that owns the walk stack 888 * Op - The control Op 889 * 890 * RETURN: Status 891 * 892 * DESCRIPTION: Handles all control ops encountered during control method 893 * execution. 894 * 895 ******************************************************************************/ 896 897acpi_status 898acpi_ds_exec_begin_control_op ( 899 struct acpi_walk_state *walk_state, 900 union acpi_parse_object *op) 901{ 902 acpi_status status = AE_OK; 903 union acpi_generic_state *control_state; 904 905 906 ACPI_FUNCTION_NAME ("ds_exec_begin_control_op"); 907 908 909 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Op=%p Opcode=%2.2X State=%p\n", op, 910 op->common.aml_opcode, walk_state)); 911 912 switch (op->common.aml_opcode) { 913 case AML_IF_OP: 914 case AML_WHILE_OP: 915 916 /* 917 * IF/WHILE: Create a new control state to manage these 918 * constructs. We need to manage these as a stack, in order 919 * to handle nesting. 920 */ 921 control_state = acpi_ut_create_control_state (); 922 if (!control_state) { 923 status = AE_NO_MEMORY; 924 break; 925 } 926 /* 927 * Save a pointer to the predicate for multiple executions 928 * of a loop 929 */ 930 control_state->control.aml_predicate_start = walk_state->parser_state.aml - 1; 931 control_state->control.package_end = walk_state->parser_state.pkg_end; 932 control_state->control.opcode = op->common.aml_opcode; 933 934 935 /* Push the control state on this walk's control stack */ 936 937 acpi_ut_push_generic_state (&walk_state->control_state, control_state); 938 break; 939 940 case AML_ELSE_OP: 941 942 /* Predicate is in the state object */ 943 /* If predicate is true, the IF was executed, ignore ELSE part */ 944 945 if (walk_state->last_predicate) { 946 status = AE_CTRL_TRUE; 947 } 948 949 break; 950 951 case AML_RETURN_OP: 952 953 break; 954 955 default: 956 break; 957 } 958 959 return (status); 960} 961 962 963/******************************************************************************* 964 * 965 * FUNCTION: acpi_ds_exec_end_control_op 966 * 967 * PARAMETERS: walk_list - The list that owns the walk stack 968 * Op - The control Op 969 * 970 * RETURN: Status 971 * 972 * DESCRIPTION: Handles all control ops encountered during control method 973 * execution. 974 * 975 ******************************************************************************/ 976 977acpi_status 978acpi_ds_exec_end_control_op ( 979 struct acpi_walk_state *walk_state, 980 union acpi_parse_object *op) 981{ 982 acpi_status status = AE_OK; 983 union acpi_generic_state *control_state; 984 985 986 ACPI_FUNCTION_NAME ("ds_exec_end_control_op"); 987 988 989 switch (op->common.aml_opcode) { 990 case AML_IF_OP: 991 992 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "[IF_OP] Op=%p\n", op)); 993 994 /* 995 * Save the result of the predicate in case there is an 996 * ELSE to come 997 */ 998 walk_state->last_predicate = 999 (u8) walk_state->control_state->common.value; 1000 1001 /* 1002 * Pop the control state that was created at the start 1003 * of the IF and free it 1004 */ 1005 control_state = acpi_ut_pop_generic_state (&walk_state->control_state); 1006 acpi_ut_delete_generic_state (control_state); 1007 break; 1008 1009 1010 case AML_ELSE_OP: 1011 1012 break; 1013 1014 1015 case AML_WHILE_OP: 1016 1017 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "[WHILE_OP] Op=%p\n", op)); 1018 1019 if (walk_state->control_state->common.value) { 1020 /* Predicate was true, go back and evaluate it again! */ 1021 1022 status = AE_CTRL_PENDING; 1023 } 1024 1025 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, 1026 "[WHILE_OP] termination! Op=%p\n",op)); 1027 1028 /* Pop this control state and free it */ 1029 1030 control_state = acpi_ut_pop_generic_state (&walk_state->control_state); 1031 1032 walk_state->aml_last_while = control_state->control.aml_predicate_start; 1033 acpi_ut_delete_generic_state (control_state); 1034 break; 1035 1036 1037 case AML_RETURN_OP: 1038 1039 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, 1040 "[RETURN_OP] Op=%p Arg=%p\n",op, op->common.value.arg)); 1041 1042 /* 1043 * One optional operand -- the return value 1044 * It can be either an immediate operand or a result that 1045 * has been bubbled up the tree 1046 */ 1047 if (op->common.value.arg) { 1048 /* Since we have a real Return(), delete any implicit return */ 1049 1050 acpi_ds_clear_implicit_return (walk_state); 1051 1052 /* Return statement has an immediate operand */ 1053 1054 status = acpi_ds_create_operands (walk_state, op->common.value.arg); 1055 if (ACPI_FAILURE (status)) { 1056 return (status); 1057 } 1058 1059 /* 1060 * If value being returned is a Reference (such as 1061 * an arg or local), resolve it now because it may 1062 * cease to exist at the end of the method. 1063 */ 1064 status = acpi_ex_resolve_to_value (&walk_state->operands [0], walk_state); 1065 if (ACPI_FAILURE (status)) { 1066 return (status); 1067 } 1068 1069 /* 1070 * Get the return value and save as the last result 1071 * value. This is the only place where walk_state->return_desc 1072 * is set to anything other than zero! 1073 */ 1074 walk_state->return_desc = walk_state->operands[0]; 1075 } 1076 else if ((walk_state->results) && 1077 (walk_state->results->results.num_results > 0)) { 1078 /* Since we have a real Return(), delete any implicit return */ 1079 1080 acpi_ds_clear_implicit_return (walk_state); 1081 1082 /* 1083 * The return value has come from a previous calculation. 1084 * 1085 * If value being returned is a Reference (such as 1086 * an arg or local), resolve it now because it may 1087 * cease to exist at the end of the method. 1088 * 1089 * Allow references created by the Index operator to return unchanged. 1090 */ 1091 if ((ACPI_GET_DESCRIPTOR_TYPE (walk_state->results->results.obj_desc[0]) == ACPI_DESC_TYPE_OPERAND) && 1092 (ACPI_GET_OBJECT_TYPE (walk_state->results->results.obj_desc [0]) == ACPI_TYPE_LOCAL_REFERENCE) && 1093 ((walk_state->results->results.obj_desc [0])->reference.opcode != AML_INDEX_OP)) { 1094 status = acpi_ex_resolve_to_value (&walk_state->results->results.obj_desc [0], walk_state); 1095 if (ACPI_FAILURE (status)) { 1096 return (status); 1097 } 1098 } 1099 1100 walk_state->return_desc = walk_state->results->results.obj_desc [0]; 1101 } 1102 else { 1103 /* No return operand */ 1104 1105 if (walk_state->num_operands) { 1106 acpi_ut_remove_reference (walk_state->operands [0]); 1107 } 1108 1109 walk_state->operands [0] = NULL; 1110 walk_state->num_operands = 0; 1111 walk_state->return_desc = NULL; 1112 } 1113 1114 1115 ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, 1116 "Completed RETURN_OP State=%p, ret_val=%p\n", 1117 walk_state, walk_state->return_desc)); 1118 1119 /* End the control method execution right now */ 1120 1121 status = AE_CTRL_TERMINATE; 1122 break; 1123 1124 1125 case AML_NOOP_OP: 1126 1127 /* Just do nothing! */ 1128 break; 1129 1130 1131 case AML_BREAK_POINT_OP: 1132 1133 /* Call up to the OS service layer to handle this */ 1134 1135 status = acpi_os_signal (ACPI_SIGNAL_BREAKPOINT, "Executed AML Breakpoint opcode"); 1136 1137 /* If and when it returns, all done. */ 1138 1139 break; 1140 1141 1142 case AML_BREAK_OP: 1143 case AML_CONTINUE_OP: /* ACPI 2.0 */ 1144 1145 1146 /* Pop and delete control states until we find a while */ 1147 1148 while (walk_state->control_state && 1149 (walk_state->control_state->control.opcode != AML_WHILE_OP)) { 1150 control_state = acpi_ut_pop_generic_state (&walk_state->control_state); 1151 acpi_ut_delete_generic_state (control_state); 1152 } 1153 1154 /* No while found? */ 1155 1156 if (!walk_state->control_state) { 1157 return (AE_AML_NO_WHILE); 1158 } 1159 1160 /* Was: walk_state->aml_last_while = walk_state->control_state->Control.aml_predicate_start; */ 1161 1162 walk_state->aml_last_while = walk_state->control_state->control.package_end; 1163 1164 /* Return status depending on opcode */ 1165 1166 if (op->common.aml_opcode == AML_BREAK_OP) { 1167 status = AE_CTRL_BREAK; 1168 } 1169 else { 1170 status = AE_CTRL_CONTINUE; 1171 } 1172 break; 1173 1174 1175 default: 1176 1177 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown control opcode=%X Op=%p\n", 1178 op->common.aml_opcode, op)); 1179 1180 status = AE_AML_BAD_OPCODE; 1181 break; 1182 } 1183 1184 return (status); 1185} 1186