1 /****************************************************************************** 2 * 3 * Module Name: exmisc - ACPI AML (p-code) execution - specific opcodes 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2015, 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 "acinterp.h" 47 #include "amlcode.h" 48 #include "amlresrc.h" 49 50 #define _COMPONENT ACPI_EXECUTER 51 ACPI_MODULE_NAME("exmisc") 52 53 /******************************************************************************* 54 * 55 * FUNCTION: acpi_ex_get_object_reference 56 * 57 * PARAMETERS: obj_desc - Create a reference to this object 58 * return_desc - Where to store the reference 59 * walk_state - Current state 60 * 61 * RETURN: Status 62 * 63 * DESCRIPTION: Obtain and return a "reference" to the target object 64 * Common code for the ref_of_op and the cond_ref_of_op. 65 * 66 ******************************************************************************/ 67 acpi_status 68 acpi_ex_get_object_reference(union acpi_operand_object *obj_desc, 69 union acpi_operand_object **return_desc, 70 struct acpi_walk_state *walk_state) 71 { 72 union acpi_operand_object *reference_obj; 73 union acpi_operand_object *referenced_obj; 74 75 ACPI_FUNCTION_TRACE_PTR(ex_get_object_reference, obj_desc); 76 77 *return_desc = NULL; 78 79 switch (ACPI_GET_DESCRIPTOR_TYPE(obj_desc)) { 80 case ACPI_DESC_TYPE_OPERAND: 81 82 if (obj_desc->common.type != ACPI_TYPE_LOCAL_REFERENCE) { 83 return_ACPI_STATUS(AE_AML_OPERAND_TYPE); 84 } 85 86 /* 87 * Must be a reference to a Local or Arg 88 */ 89 switch (obj_desc->reference.class) { 90 case ACPI_REFCLASS_LOCAL: 91 case ACPI_REFCLASS_ARG: 92 case ACPI_REFCLASS_DEBUG: 93 94 /* The referenced object is the pseudo-node for the local/arg */ 95 96 referenced_obj = obj_desc->reference.object; 97 break; 98 99 default: 100 101 ACPI_ERROR((AE_INFO, "Unknown Reference Class 0x%2.2X", 102 obj_desc->reference.class)); 103 return_ACPI_STATUS(AE_AML_INTERNAL); 104 } 105 break; 106 107 case ACPI_DESC_TYPE_NAMED: 108 /* 109 * A named reference that has already been resolved to a Node 110 */ 111 referenced_obj = obj_desc; 112 break; 113 114 default: 115 116 ACPI_ERROR((AE_INFO, "Invalid descriptor type 0x%X", 117 ACPI_GET_DESCRIPTOR_TYPE(obj_desc))); 118 return_ACPI_STATUS(AE_TYPE); 119 } 120 121 /* Create a new reference object */ 122 123 reference_obj = 124 acpi_ut_create_internal_object(ACPI_TYPE_LOCAL_REFERENCE); 125 if (!reference_obj) { 126 return_ACPI_STATUS(AE_NO_MEMORY); 127 } 128 129 reference_obj->reference.class = ACPI_REFCLASS_REFOF; 130 reference_obj->reference.object = referenced_obj; 131 *return_desc = reference_obj; 132 133 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, 134 "Object %p Type [%s], returning Reference %p\n", 135 obj_desc, acpi_ut_get_object_type_name(obj_desc), 136 *return_desc)); 137 138 return_ACPI_STATUS(AE_OK); 139 } 140 141 /******************************************************************************* 142 * 143 * FUNCTION: acpi_ex_concat_template 144 * 145 * PARAMETERS: operand0 - First source object 146 * operand1 - Second source object 147 * actual_return_desc - Where to place the return object 148 * walk_state - Current walk state 149 * 150 * RETURN: Status 151 * 152 * DESCRIPTION: Concatenate two resource templates 153 * 154 ******************************************************************************/ 155 156 acpi_status 157 acpi_ex_concat_template(union acpi_operand_object *operand0, 158 union acpi_operand_object *operand1, 159 union acpi_operand_object **actual_return_desc, 160 struct acpi_walk_state *walk_state) 161 { 162 acpi_status status; 163 union acpi_operand_object *return_desc; 164 u8 *new_buf; 165 u8 *end_tag; 166 acpi_size length0; 167 acpi_size length1; 168 acpi_size new_length; 169 170 ACPI_FUNCTION_TRACE(ex_concat_template); 171 172 /* 173 * Find the end_tag descriptor in each resource template. 174 * Note1: returned pointers point TO the end_tag, not past it. 175 * Note2: zero-length buffers are allowed; treated like one end_tag 176 */ 177 178 /* Get the length of the first resource template */ 179 180 status = acpi_ut_get_resource_end_tag(operand0, &end_tag); 181 if (ACPI_FAILURE(status)) { 182 return_ACPI_STATUS(status); 183 } 184 185 length0 = ACPI_PTR_DIFF(end_tag, operand0->buffer.pointer); 186 187 /* Get the length of the second resource template */ 188 189 status = acpi_ut_get_resource_end_tag(operand1, &end_tag); 190 if (ACPI_FAILURE(status)) { 191 return_ACPI_STATUS(status); 192 } 193 194 length1 = ACPI_PTR_DIFF(end_tag, operand1->buffer.pointer); 195 196 /* Combine both lengths, minimum size will be 2 for end_tag */ 197 198 new_length = length0 + length1 + sizeof(struct aml_resource_end_tag); 199 200 /* Create a new buffer object for the result (with one end_tag) */ 201 202 return_desc = acpi_ut_create_buffer_object(new_length); 203 if (!return_desc) { 204 return_ACPI_STATUS(AE_NO_MEMORY); 205 } 206 207 /* 208 * Copy the templates to the new buffer, 0 first, then 1 follows. One 209 * end_tag descriptor is copied from Operand1. 210 */ 211 new_buf = return_desc->buffer.pointer; 212 memcpy(new_buf, operand0->buffer.pointer, length0); 213 memcpy(new_buf + length0, operand1->buffer.pointer, length1); 214 215 /* Insert end_tag and set the checksum to zero, means "ignore checksum" */ 216 217 new_buf[new_length - 1] = 0; 218 new_buf[new_length - 2] = ACPI_RESOURCE_NAME_END_TAG | 1; 219 220 /* Return the completed resource template */ 221 222 *actual_return_desc = return_desc; 223 return_ACPI_STATUS(AE_OK); 224 } 225 226 /******************************************************************************* 227 * 228 * FUNCTION: acpi_ex_do_concatenate 229 * 230 * PARAMETERS: operand0 - First source object 231 * operand1 - Second source object 232 * actual_return_desc - Where to place the return object 233 * walk_state - Current walk state 234 * 235 * RETURN: Status 236 * 237 * DESCRIPTION: Concatenate two objects OF THE SAME TYPE. 238 * 239 ******************************************************************************/ 240 241 acpi_status 242 acpi_ex_do_concatenate(union acpi_operand_object *operand0, 243 union acpi_operand_object *operand1, 244 union acpi_operand_object **actual_return_desc, 245 struct acpi_walk_state *walk_state) 246 { 247 union acpi_operand_object *local_operand1 = operand1; 248 union acpi_operand_object *return_desc; 249 char *new_buf; 250 acpi_status status; 251 252 ACPI_FUNCTION_TRACE(ex_do_concatenate); 253 254 /* 255 * Convert the second operand if necessary. The first operand 256 * determines the type of the second operand, (See the Data Types 257 * section of the ACPI specification.) Both object types are 258 * guaranteed to be either Integer/String/Buffer by the operand 259 * resolution mechanism. 260 */ 261 switch (operand0->common.type) { 262 case ACPI_TYPE_INTEGER: 263 264 status = 265 acpi_ex_convert_to_integer(operand1, &local_operand1, 16); 266 break; 267 268 case ACPI_TYPE_STRING: 269 270 status = acpi_ex_convert_to_string(operand1, &local_operand1, 271 ACPI_IMPLICIT_CONVERT_HEX); 272 break; 273 274 case ACPI_TYPE_BUFFER: 275 276 status = acpi_ex_convert_to_buffer(operand1, &local_operand1); 277 break; 278 279 default: 280 281 ACPI_ERROR((AE_INFO, "Invalid object type: 0x%X", 282 operand0->common.type)); 283 status = AE_AML_INTERNAL; 284 } 285 286 if (ACPI_FAILURE(status)) { 287 goto cleanup; 288 } 289 290 /* 291 * Both operands are now known to be the same object type 292 * (Both are Integer, String, or Buffer), and we can now perform the 293 * concatenation. 294 */ 295 296 /* 297 * There are three cases to handle: 298 * 299 * 1) Two Integers concatenated to produce a new Buffer 300 * 2) Two Strings concatenated to produce a new String 301 * 3) Two Buffers concatenated to produce a new Buffer 302 */ 303 switch (operand0->common.type) { 304 case ACPI_TYPE_INTEGER: 305 306 /* Result of two Integers is a Buffer */ 307 /* Need enough buffer space for two integers */ 308 309 return_desc = acpi_ut_create_buffer_object((acpi_size) 310 ACPI_MUL_2 311 (acpi_gbl_integer_byte_width)); 312 if (!return_desc) { 313 status = AE_NO_MEMORY; 314 goto cleanup; 315 } 316 317 new_buf = (char *)return_desc->buffer.pointer; 318 319 /* Copy the first integer, LSB first */ 320 321 memcpy(new_buf, &operand0->integer.value, 322 acpi_gbl_integer_byte_width); 323 324 /* Copy the second integer (LSB first) after the first */ 325 326 memcpy(new_buf + acpi_gbl_integer_byte_width, 327 &local_operand1->integer.value, 328 acpi_gbl_integer_byte_width); 329 break; 330 331 case ACPI_TYPE_STRING: 332 333 /* Result of two Strings is a String */ 334 335 return_desc = acpi_ut_create_string_object(((acpi_size) 336 operand0->string. 337 length + 338 local_operand1-> 339 string.length)); 340 if (!return_desc) { 341 status = AE_NO_MEMORY; 342 goto cleanup; 343 } 344 345 new_buf = return_desc->string.pointer; 346 347 /* Concatenate the strings */ 348 349 strcpy(new_buf, operand0->string.pointer); 350 strcpy(new_buf + operand0->string.length, 351 local_operand1->string.pointer); 352 break; 353 354 case ACPI_TYPE_BUFFER: 355 356 /* Result of two Buffers is a Buffer */ 357 358 return_desc = acpi_ut_create_buffer_object(((acpi_size) 359 operand0->buffer. 360 length + 361 local_operand1-> 362 buffer.length)); 363 if (!return_desc) { 364 status = AE_NO_MEMORY; 365 goto cleanup; 366 } 367 368 new_buf = (char *)return_desc->buffer.pointer; 369 370 /* Concatenate the buffers */ 371 372 memcpy(new_buf, operand0->buffer.pointer, 373 operand0->buffer.length); 374 memcpy(new_buf + operand0->buffer.length, 375 local_operand1->buffer.pointer, 376 local_operand1->buffer.length); 377 break; 378 379 default: 380 381 /* Invalid object type, should not happen here */ 382 383 ACPI_ERROR((AE_INFO, "Invalid object type: 0x%X", 384 operand0->common.type)); 385 status = AE_AML_INTERNAL; 386 goto cleanup; 387 } 388 389 *actual_return_desc = return_desc; 390 391 cleanup: 392 if (local_operand1 != operand1) { 393 acpi_ut_remove_reference(local_operand1); 394 } 395 return_ACPI_STATUS(status); 396 } 397 398 /******************************************************************************* 399 * 400 * FUNCTION: acpi_ex_do_math_op 401 * 402 * PARAMETERS: opcode - AML opcode 403 * integer0 - Integer operand #0 404 * integer1 - Integer operand #1 405 * 406 * RETURN: Integer result of the operation 407 * 408 * DESCRIPTION: Execute a math AML opcode. The purpose of having all of the 409 * math functions here is to prevent a lot of pointer dereferencing 410 * to obtain the operands. 411 * 412 ******************************************************************************/ 413 414 u64 acpi_ex_do_math_op(u16 opcode, u64 integer0, u64 integer1) 415 { 416 417 ACPI_FUNCTION_ENTRY(); 418 419 switch (opcode) { 420 case AML_ADD_OP: /* Add (Integer0, Integer1, Result) */ 421 422 return (integer0 + integer1); 423 424 case AML_BIT_AND_OP: /* And (Integer0, Integer1, Result) */ 425 426 return (integer0 & integer1); 427 428 case AML_BIT_NAND_OP: /* NAnd (Integer0, Integer1, Result) */ 429 430 return (~(integer0 & integer1)); 431 432 case AML_BIT_OR_OP: /* Or (Integer0, Integer1, Result) */ 433 434 return (integer0 | integer1); 435 436 case AML_BIT_NOR_OP: /* NOr (Integer0, Integer1, Result) */ 437 438 return (~(integer0 | integer1)); 439 440 case AML_BIT_XOR_OP: /* XOr (Integer0, Integer1, Result) */ 441 442 return (integer0 ^ integer1); 443 444 case AML_MULTIPLY_OP: /* Multiply (Integer0, Integer1, Result) */ 445 446 return (integer0 * integer1); 447 448 case AML_SHIFT_LEFT_OP: /* shift_left (Operand, shift_count, Result) */ 449 450 /* 451 * We need to check if the shiftcount is larger than the integer bit 452 * width since the behavior of this is not well-defined in the C language. 453 */ 454 if (integer1 >= acpi_gbl_integer_bit_width) { 455 return (0); 456 } 457 return (integer0 << integer1); 458 459 case AML_SHIFT_RIGHT_OP: /* shift_right (Operand, shift_count, Result) */ 460 461 /* 462 * We need to check if the shiftcount is larger than the integer bit 463 * width since the behavior of this is not well-defined in the C language. 464 */ 465 if (integer1 >= acpi_gbl_integer_bit_width) { 466 return (0); 467 } 468 return (integer0 >> integer1); 469 470 case AML_SUBTRACT_OP: /* Subtract (Integer0, Integer1, Result) */ 471 472 return (integer0 - integer1); 473 474 default: 475 476 return (0); 477 } 478 } 479 480 /******************************************************************************* 481 * 482 * FUNCTION: acpi_ex_do_logical_numeric_op 483 * 484 * PARAMETERS: opcode - AML opcode 485 * integer0 - Integer operand #0 486 * integer1 - Integer operand #1 487 * logical_result - TRUE/FALSE result of the operation 488 * 489 * RETURN: Status 490 * 491 * DESCRIPTION: Execute a logical "Numeric" AML opcode. For these Numeric 492 * operators (LAnd and LOr), both operands must be integers. 493 * 494 * Note: cleanest machine code seems to be produced by the code 495 * below, rather than using statements of the form: 496 * Result = (Integer0 && Integer1); 497 * 498 ******************************************************************************/ 499 500 acpi_status 501 acpi_ex_do_logical_numeric_op(u16 opcode, 502 u64 integer0, u64 integer1, u8 *logical_result) 503 { 504 acpi_status status = AE_OK; 505 u8 local_result = FALSE; 506 507 ACPI_FUNCTION_TRACE(ex_do_logical_numeric_op); 508 509 switch (opcode) { 510 case AML_LAND_OP: /* LAnd (Integer0, Integer1) */ 511 512 if (integer0 && integer1) { 513 local_result = TRUE; 514 } 515 break; 516 517 case AML_LOR_OP: /* LOr (Integer0, Integer1) */ 518 519 if (integer0 || integer1) { 520 local_result = TRUE; 521 } 522 break; 523 524 default: 525 526 status = AE_AML_INTERNAL; 527 break; 528 } 529 530 /* Return the logical result and status */ 531 532 *logical_result = local_result; 533 return_ACPI_STATUS(status); 534 } 535 536 /******************************************************************************* 537 * 538 * FUNCTION: acpi_ex_do_logical_op 539 * 540 * PARAMETERS: opcode - AML opcode 541 * operand0 - operand #0 542 * operand1 - operand #1 543 * logical_result - TRUE/FALSE result of the operation 544 * 545 * RETURN: Status 546 * 547 * DESCRIPTION: Execute a logical AML opcode. The purpose of having all of the 548 * functions here is to prevent a lot of pointer dereferencing 549 * to obtain the operands and to simplify the generation of the 550 * logical value. For the Numeric operators (LAnd and LOr), both 551 * operands must be integers. For the other logical operators, 552 * operands can be any combination of Integer/String/Buffer. The 553 * first operand determines the type to which the second operand 554 * will be converted. 555 * 556 * Note: cleanest machine code seems to be produced by the code 557 * below, rather than using statements of the form: 558 * Result = (Operand0 == Operand1); 559 * 560 ******************************************************************************/ 561 562 acpi_status 563 acpi_ex_do_logical_op(u16 opcode, 564 union acpi_operand_object *operand0, 565 union acpi_operand_object *operand1, u8 * logical_result) 566 { 567 union acpi_operand_object *local_operand1 = operand1; 568 u64 integer0; 569 u64 integer1; 570 u32 length0; 571 u32 length1; 572 acpi_status status = AE_OK; 573 u8 local_result = FALSE; 574 int compare; 575 576 ACPI_FUNCTION_TRACE(ex_do_logical_op); 577 578 /* 579 * Convert the second operand if necessary. The first operand 580 * determines the type of the second operand, (See the Data Types 581 * section of the ACPI 3.0+ specification.) Both object types are 582 * guaranteed to be either Integer/String/Buffer by the operand 583 * resolution mechanism. 584 */ 585 switch (operand0->common.type) { 586 case ACPI_TYPE_INTEGER: 587 588 status = 589 acpi_ex_convert_to_integer(operand1, &local_operand1, 16); 590 break; 591 592 case ACPI_TYPE_STRING: 593 594 status = acpi_ex_convert_to_string(operand1, &local_operand1, 595 ACPI_IMPLICIT_CONVERT_HEX); 596 break; 597 598 case ACPI_TYPE_BUFFER: 599 600 status = acpi_ex_convert_to_buffer(operand1, &local_operand1); 601 break; 602 603 default: 604 605 status = AE_AML_INTERNAL; 606 break; 607 } 608 609 if (ACPI_FAILURE(status)) { 610 goto cleanup; 611 } 612 613 /* 614 * Two cases: 1) Both Integers, 2) Both Strings or Buffers 615 */ 616 if (operand0->common.type == ACPI_TYPE_INTEGER) { 617 /* 618 * 1) Both operands are of type integer 619 * Note: local_operand1 may have changed above 620 */ 621 integer0 = operand0->integer.value; 622 integer1 = local_operand1->integer.value; 623 624 switch (opcode) { 625 case AML_LEQUAL_OP: /* LEqual (Operand0, Operand1) */ 626 627 if (integer0 == integer1) { 628 local_result = TRUE; 629 } 630 break; 631 632 case AML_LGREATER_OP: /* LGreater (Operand0, Operand1) */ 633 634 if (integer0 > integer1) { 635 local_result = TRUE; 636 } 637 break; 638 639 case AML_LLESS_OP: /* LLess (Operand0, Operand1) */ 640 641 if (integer0 < integer1) { 642 local_result = TRUE; 643 } 644 break; 645 646 default: 647 648 status = AE_AML_INTERNAL; 649 break; 650 } 651 } else { 652 /* 653 * 2) Both operands are Strings or both are Buffers 654 * Note: Code below takes advantage of common Buffer/String 655 * object fields. local_operand1 may have changed above. Use 656 * memcmp to handle nulls in buffers. 657 */ 658 length0 = operand0->buffer.length; 659 length1 = local_operand1->buffer.length; 660 661 /* Lexicographic compare: compare the data bytes */ 662 663 compare = memcmp(operand0->buffer.pointer, 664 local_operand1->buffer.pointer, 665 (length0 > length1) ? length1 : length0); 666 667 switch (opcode) { 668 case AML_LEQUAL_OP: /* LEqual (Operand0, Operand1) */ 669 670 /* Length and all bytes must be equal */ 671 672 if ((length0 == length1) && (compare == 0)) { 673 674 /* Length and all bytes match ==> TRUE */ 675 676 local_result = TRUE; 677 } 678 break; 679 680 case AML_LGREATER_OP: /* LGreater (Operand0, Operand1) */ 681 682 if (compare > 0) { 683 local_result = TRUE; 684 goto cleanup; /* TRUE */ 685 } 686 if (compare < 0) { 687 goto cleanup; /* FALSE */ 688 } 689 690 /* Bytes match (to shortest length), compare lengths */ 691 692 if (length0 > length1) { 693 local_result = TRUE; 694 } 695 break; 696 697 case AML_LLESS_OP: /* LLess (Operand0, Operand1) */ 698 699 if (compare > 0) { 700 goto cleanup; /* FALSE */ 701 } 702 if (compare < 0) { 703 local_result = TRUE; 704 goto cleanup; /* TRUE */ 705 } 706 707 /* Bytes match (to shortest length), compare lengths */ 708 709 if (length0 < length1) { 710 local_result = TRUE; 711 } 712 break; 713 714 default: 715 716 status = AE_AML_INTERNAL; 717 break; 718 } 719 } 720 721 cleanup: 722 723 /* New object was created if implicit conversion performed - delete */ 724 725 if (local_operand1 != operand1) { 726 acpi_ut_remove_reference(local_operand1); 727 } 728 729 /* Return the logical result and status */ 730 731 *logical_result = local_result; 732 return_ACPI_STATUS(status); 733 } 734