1 /****************************************************************************** 2 * 3 * Module Name: exresop - AML Interpreter operand/object resolution 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2016, 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.h" 45 #include "accommon.h" 46 #include "amlcode.h" 47 #include "acparser.h" 48 #include "acinterp.h" 49 #include "acnamesp.h" 50 51 52 #define _COMPONENT ACPI_EXECUTER 53 ACPI_MODULE_NAME ("exresop") 54 55 /* Local prototypes */ 56 57 static ACPI_STATUS 58 AcpiExCheckObjectType ( 59 ACPI_OBJECT_TYPE TypeNeeded, 60 ACPI_OBJECT_TYPE ThisType, 61 void *Object); 62 63 64 /******************************************************************************* 65 * 66 * FUNCTION: AcpiExCheckObjectType 67 * 68 * PARAMETERS: TypeNeeded Object type needed 69 * ThisType Actual object type 70 * Object Object pointer 71 * 72 * RETURN: Status 73 * 74 * DESCRIPTION: Check required type against actual type 75 * 76 ******************************************************************************/ 77 78 static ACPI_STATUS 79 AcpiExCheckObjectType ( 80 ACPI_OBJECT_TYPE TypeNeeded, 81 ACPI_OBJECT_TYPE ThisType, 82 void *Object) 83 { 84 ACPI_FUNCTION_ENTRY (); 85 86 87 if (TypeNeeded == ACPI_TYPE_ANY) 88 { 89 /* All types OK, so we don't perform any typechecks */ 90 91 return (AE_OK); 92 } 93 94 if (TypeNeeded == ACPI_TYPE_LOCAL_REFERENCE) 95 { 96 /* 97 * Allow the AML "Constant" opcodes (Zero, One, etc.) to be reference 98 * objects and thus allow them to be targets. (As per the ACPI 99 * specification, a store to a constant is a noop.) 100 */ 101 if ((ThisType == ACPI_TYPE_INTEGER) && 102 (((ACPI_OPERAND_OBJECT *) Object)->Common.Flags & 103 AOPOBJ_AML_CONSTANT)) 104 { 105 return (AE_OK); 106 } 107 } 108 109 if (TypeNeeded != ThisType) 110 { 111 ACPI_ERROR ((AE_INFO, 112 "Needed type [%s], found [%s] %p", 113 AcpiUtGetTypeName (TypeNeeded), 114 AcpiUtGetTypeName (ThisType), Object)); 115 116 return (AE_AML_OPERAND_TYPE); 117 } 118 119 return (AE_OK); 120 } 121 122 123 /******************************************************************************* 124 * 125 * FUNCTION: AcpiExResolveOperands 126 * 127 * PARAMETERS: Opcode - Opcode being interpreted 128 * StackPtr - Pointer to the operand stack to be 129 * resolved 130 * WalkState - Current state 131 * 132 * RETURN: Status 133 * 134 * DESCRIPTION: Convert multiple input operands to the types required by the 135 * target operator. 136 * 137 * Each 5-bit group in ArgTypes represents one required 138 * operand and indicates the required Type. The corresponding operand 139 * will be converted to the required type if possible, otherwise we 140 * abort with an exception. 141 * 142 ******************************************************************************/ 143 144 ACPI_STATUS 145 AcpiExResolveOperands ( 146 UINT16 Opcode, 147 ACPI_OPERAND_OBJECT **StackPtr, 148 ACPI_WALK_STATE *WalkState) 149 { 150 ACPI_OPERAND_OBJECT *ObjDesc; 151 ACPI_STATUS Status = AE_OK; 152 UINT8 ObjectType; 153 UINT32 ArgTypes; 154 const ACPI_OPCODE_INFO *OpInfo; 155 UINT32 ThisArgType; 156 ACPI_OBJECT_TYPE TypeNeeded; 157 UINT16 TargetOp = 0; 158 159 160 ACPI_FUNCTION_TRACE_U32 (ExResolveOperands, Opcode); 161 162 163 OpInfo = AcpiPsGetOpcodeInfo (Opcode); 164 if (OpInfo->Class == AML_CLASS_UNKNOWN) 165 { 166 return_ACPI_STATUS (AE_AML_BAD_OPCODE); 167 } 168 169 ArgTypes = OpInfo->RuntimeArgs; 170 if (ArgTypes == ARGI_INVALID_OPCODE) 171 { 172 ACPI_ERROR ((AE_INFO, "Unknown AML opcode 0x%X", 173 Opcode)); 174 175 return_ACPI_STATUS (AE_AML_INTERNAL); 176 } 177 178 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, 179 "Opcode %X [%s] RequiredOperandTypes=%8.8X\n", 180 Opcode, OpInfo->Name, ArgTypes)); 181 182 /* 183 * Normal exit is with (ArgTypes == 0) at end of argument list. 184 * Function will return an exception from within the loop upon 185 * finding an entry which is not (or cannot be converted 186 * to) the required type; if stack underflows; or upon 187 * finding a NULL stack entry (which should not happen). 188 */ 189 while (GET_CURRENT_ARG_TYPE (ArgTypes)) 190 { 191 if (!StackPtr || !*StackPtr) 192 { 193 ACPI_ERROR ((AE_INFO, "Null stack entry at %p", 194 StackPtr)); 195 196 return_ACPI_STATUS (AE_AML_INTERNAL); 197 } 198 199 /* Extract useful items */ 200 201 ObjDesc = *StackPtr; 202 203 /* Decode the descriptor type */ 204 205 switch (ACPI_GET_DESCRIPTOR_TYPE (ObjDesc)) 206 { 207 case ACPI_DESC_TYPE_NAMED: 208 209 /* Namespace Node */ 210 211 ObjectType = ((ACPI_NAMESPACE_NODE *) ObjDesc)->Type; 212 213 /* 214 * Resolve an alias object. The construction of these objects 215 * guarantees that there is only one level of alias indirection; 216 * thus, the attached object is always the aliased namespace node 217 */ 218 if (ObjectType == ACPI_TYPE_LOCAL_ALIAS) 219 { 220 ObjDesc = AcpiNsGetAttachedObject ( 221 (ACPI_NAMESPACE_NODE *) ObjDesc); 222 *StackPtr = ObjDesc; 223 ObjectType = ((ACPI_NAMESPACE_NODE *) ObjDesc)->Type; 224 } 225 break; 226 227 case ACPI_DESC_TYPE_OPERAND: 228 229 /* ACPI internal object */ 230 231 ObjectType = ObjDesc->Common.Type; 232 233 /* Check for bad ACPI_OBJECT_TYPE */ 234 235 if (!AcpiUtValidObjectType (ObjectType)) 236 { 237 ACPI_ERROR ((AE_INFO, 238 "Bad operand object type [0x%X]", ObjectType)); 239 240 return_ACPI_STATUS (AE_AML_OPERAND_TYPE); 241 } 242 243 if (ObjectType == (UINT8) ACPI_TYPE_LOCAL_REFERENCE) 244 { 245 /* Validate the Reference */ 246 247 switch (ObjDesc->Reference.Class) 248 { 249 case ACPI_REFCLASS_DEBUG: 250 251 TargetOp = AML_DEBUG_OP; 252 253 /*lint -fallthrough */ 254 255 case ACPI_REFCLASS_ARG: 256 case ACPI_REFCLASS_LOCAL: 257 case ACPI_REFCLASS_INDEX: 258 case ACPI_REFCLASS_REFOF: 259 case ACPI_REFCLASS_TABLE: /* DdbHandle from LOAD_OP or LOAD_TABLE_OP */ 260 case ACPI_REFCLASS_NAME: /* Reference to a named object */ 261 262 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, 263 "Operand is a Reference, Class [%s] %2.2X\n", 264 AcpiUtGetReferenceName (ObjDesc), 265 ObjDesc->Reference.Class)); 266 break; 267 268 default: 269 270 ACPI_ERROR ((AE_INFO, 271 "Unknown Reference Class 0x%2.2X in %p", 272 ObjDesc->Reference.Class, ObjDesc)); 273 274 return_ACPI_STATUS (AE_AML_OPERAND_TYPE); 275 } 276 } 277 break; 278 279 default: 280 281 /* Invalid descriptor */ 282 283 ACPI_ERROR ((AE_INFO, "Invalid descriptor %p [%s]", 284 ObjDesc, AcpiUtGetDescriptorName (ObjDesc))); 285 286 return_ACPI_STATUS (AE_AML_OPERAND_TYPE); 287 } 288 289 /* Get one argument type, point to the next */ 290 291 ThisArgType = GET_CURRENT_ARG_TYPE (ArgTypes); 292 INCREMENT_ARG_LIST (ArgTypes); 293 294 /* 295 * Handle cases where the object does not need to be 296 * resolved to a value 297 */ 298 switch (ThisArgType) 299 { 300 case ARGI_REF_OR_STRING: /* Can be a String or Reference */ 301 302 if ((ACPI_GET_DESCRIPTOR_TYPE (ObjDesc) == 303 ACPI_DESC_TYPE_OPERAND) && 304 (ObjDesc->Common.Type == ACPI_TYPE_STRING)) 305 { 306 /* 307 * String found - the string references a named object and 308 * must be resolved to a node 309 */ 310 goto NextOperand; 311 } 312 313 /* 314 * Else not a string - fall through to the normal Reference 315 * case below 316 */ 317 /*lint -fallthrough */ 318 319 case ARGI_REFERENCE: /* References: */ 320 case ARGI_INTEGER_REF: 321 case ARGI_OBJECT_REF: 322 case ARGI_DEVICE_REF: 323 case ARGI_TARGETREF: /* Allows implicit conversion rules before store */ 324 case ARGI_FIXED_TARGET: /* No implicit conversion before store to target */ 325 case ARGI_SIMPLE_TARGET: /* Name, Local, or Arg - no implicit conversion */ 326 case ARGI_STORE_TARGET: 327 328 /* 329 * Need an operand of type ACPI_TYPE_LOCAL_REFERENCE 330 * A Namespace Node is OK as-is 331 */ 332 if (ACPI_GET_DESCRIPTOR_TYPE (ObjDesc) == ACPI_DESC_TYPE_NAMED) 333 { 334 goto NextOperand; 335 } 336 337 Status = AcpiExCheckObjectType ( 338 ACPI_TYPE_LOCAL_REFERENCE, ObjectType, ObjDesc); 339 if (ACPI_FAILURE (Status)) 340 { 341 return_ACPI_STATUS (Status); 342 } 343 goto NextOperand; 344 345 case ARGI_DATAREFOBJ: /* Store operator only */ 346 /* 347 * We don't want to resolve IndexOp reference objects during 348 * a store because this would be an implicit DeRefOf operation. 349 * Instead, we just want to store the reference object. 350 * -- All others must be resolved below. 351 */ 352 if ((Opcode == AML_STORE_OP) && 353 ((*StackPtr)->Common.Type == ACPI_TYPE_LOCAL_REFERENCE) && 354 ((*StackPtr)->Reference.Class == ACPI_REFCLASS_INDEX)) 355 { 356 goto NextOperand; 357 } 358 break; 359 360 default: 361 362 /* All cases covered above */ 363 364 break; 365 } 366 367 /* 368 * Resolve this object to a value 369 */ 370 Status = AcpiExResolveToValue (StackPtr, WalkState); 371 if (ACPI_FAILURE (Status)) 372 { 373 return_ACPI_STATUS (Status); 374 } 375 376 /* Get the resolved object */ 377 378 ObjDesc = *StackPtr; 379 380 /* 381 * Check the resulting object (value) type 382 */ 383 switch (ThisArgType) 384 { 385 /* 386 * For the simple cases, only one type of resolved object 387 * is allowed 388 */ 389 case ARGI_MUTEX: 390 391 /* Need an operand of type ACPI_TYPE_MUTEX */ 392 393 TypeNeeded = ACPI_TYPE_MUTEX; 394 break; 395 396 case ARGI_EVENT: 397 398 /* Need an operand of type ACPI_TYPE_EVENT */ 399 400 TypeNeeded = ACPI_TYPE_EVENT; 401 break; 402 403 case ARGI_PACKAGE: /* Package */ 404 405 /* Need an operand of type ACPI_TYPE_PACKAGE */ 406 407 TypeNeeded = ACPI_TYPE_PACKAGE; 408 break; 409 410 case ARGI_ANYTYPE: 411 412 /* Any operand type will do */ 413 414 TypeNeeded = ACPI_TYPE_ANY; 415 break; 416 417 case ARGI_DDBHANDLE: 418 419 /* Need an operand of type ACPI_TYPE_DDB_HANDLE */ 420 421 TypeNeeded = ACPI_TYPE_LOCAL_REFERENCE; 422 break; 423 424 425 /* 426 * The more complex cases allow multiple resolved object types 427 */ 428 case ARGI_INTEGER: 429 430 /* 431 * Need an operand of type ACPI_TYPE_INTEGER, 432 * But we can implicitly convert from a STRING or BUFFER 433 * Aka - "Implicit Source Operand Conversion" 434 */ 435 Status = AcpiExConvertToInteger (ObjDesc, StackPtr, 16); 436 if (ACPI_FAILURE (Status)) 437 { 438 if (Status == AE_TYPE) 439 { 440 ACPI_ERROR ((AE_INFO, 441 "Needed [Integer/String/Buffer], found [%s] %p", 442 AcpiUtGetObjectTypeName (ObjDesc), ObjDesc)); 443 444 return_ACPI_STATUS (AE_AML_OPERAND_TYPE); 445 } 446 447 return_ACPI_STATUS (Status); 448 } 449 450 if (ObjDesc != *StackPtr) 451 { 452 AcpiUtRemoveReference (ObjDesc); 453 } 454 goto NextOperand; 455 456 case ARGI_BUFFER: 457 /* 458 * Need an operand of type ACPI_TYPE_BUFFER, 459 * But we can implicitly convert from a STRING or INTEGER 460 * Aka - "Implicit Source Operand Conversion" 461 */ 462 Status = AcpiExConvertToBuffer (ObjDesc, StackPtr); 463 if (ACPI_FAILURE (Status)) 464 { 465 if (Status == AE_TYPE) 466 { 467 ACPI_ERROR ((AE_INFO, 468 "Needed [Integer/String/Buffer], found [%s] %p", 469 AcpiUtGetObjectTypeName (ObjDesc), ObjDesc)); 470 471 return_ACPI_STATUS (AE_AML_OPERAND_TYPE); 472 } 473 474 return_ACPI_STATUS (Status); 475 } 476 477 if (ObjDesc != *StackPtr) 478 { 479 AcpiUtRemoveReference (ObjDesc); 480 } 481 goto NextOperand; 482 483 case ARGI_STRING: 484 /* 485 * Need an operand of type ACPI_TYPE_STRING, 486 * But we can implicitly convert from a BUFFER or INTEGER 487 * Aka - "Implicit Source Operand Conversion" 488 */ 489 Status = AcpiExConvertToString ( 490 ObjDesc, StackPtr, ACPI_IMPLICIT_CONVERT_HEX); 491 if (ACPI_FAILURE (Status)) 492 { 493 if (Status == AE_TYPE) 494 { 495 ACPI_ERROR ((AE_INFO, 496 "Needed [Integer/String/Buffer], found [%s] %p", 497 AcpiUtGetObjectTypeName (ObjDesc), ObjDesc)); 498 499 return_ACPI_STATUS (AE_AML_OPERAND_TYPE); 500 } 501 502 return_ACPI_STATUS (Status); 503 } 504 505 if (ObjDesc != *StackPtr) 506 { 507 AcpiUtRemoveReference (ObjDesc); 508 } 509 goto NextOperand; 510 511 case ARGI_COMPUTEDATA: 512 513 /* Need an operand of type INTEGER, STRING or BUFFER */ 514 515 switch (ObjDesc->Common.Type) 516 { 517 case ACPI_TYPE_INTEGER: 518 case ACPI_TYPE_STRING: 519 case ACPI_TYPE_BUFFER: 520 521 /* Valid operand */ 522 break; 523 524 default: 525 ACPI_ERROR ((AE_INFO, 526 "Needed [Integer/String/Buffer], found [%s] %p", 527 AcpiUtGetObjectTypeName (ObjDesc), ObjDesc)); 528 529 return_ACPI_STATUS (AE_AML_OPERAND_TYPE); 530 } 531 goto NextOperand; 532 533 case ARGI_BUFFER_OR_STRING: 534 535 /* Need an operand of type STRING or BUFFER */ 536 537 switch (ObjDesc->Common.Type) 538 { 539 case ACPI_TYPE_STRING: 540 case ACPI_TYPE_BUFFER: 541 542 /* Valid operand */ 543 break; 544 545 case ACPI_TYPE_INTEGER: 546 547 /* Highest priority conversion is to type Buffer */ 548 549 Status = AcpiExConvertToBuffer (ObjDesc, StackPtr); 550 if (ACPI_FAILURE (Status)) 551 { 552 return_ACPI_STATUS (Status); 553 } 554 555 if (ObjDesc != *StackPtr) 556 { 557 AcpiUtRemoveReference (ObjDesc); 558 } 559 break; 560 561 default: 562 ACPI_ERROR ((AE_INFO, 563 "Needed [Integer/String/Buffer], found [%s] %p", 564 AcpiUtGetObjectTypeName (ObjDesc), ObjDesc)); 565 566 return_ACPI_STATUS (AE_AML_OPERAND_TYPE); 567 } 568 goto NextOperand; 569 570 case ARGI_DATAOBJECT: 571 /* 572 * ARGI_DATAOBJECT is only used by the SizeOf operator. 573 * Need a buffer, string, package, or RefOf reference. 574 * 575 * The only reference allowed here is a direct reference to 576 * a namespace node. 577 */ 578 switch (ObjDesc->Common.Type) 579 { 580 case ACPI_TYPE_PACKAGE: 581 case ACPI_TYPE_STRING: 582 case ACPI_TYPE_BUFFER: 583 case ACPI_TYPE_LOCAL_REFERENCE: 584 585 /* Valid operand */ 586 break; 587 588 default: 589 590 ACPI_ERROR ((AE_INFO, 591 "Needed [Buffer/String/Package/Reference], found [%s] %p", 592 AcpiUtGetObjectTypeName (ObjDesc), ObjDesc)); 593 594 return_ACPI_STATUS (AE_AML_OPERAND_TYPE); 595 } 596 goto NextOperand; 597 598 case ARGI_COMPLEXOBJ: 599 600 /* Need a buffer or package or (ACPI 2.0) String */ 601 602 switch (ObjDesc->Common.Type) 603 { 604 case ACPI_TYPE_PACKAGE: 605 case ACPI_TYPE_STRING: 606 case ACPI_TYPE_BUFFER: 607 608 /* Valid operand */ 609 break; 610 611 default: 612 613 ACPI_ERROR ((AE_INFO, 614 "Needed [Buffer/String/Package], found [%s] %p", 615 AcpiUtGetObjectTypeName (ObjDesc), ObjDesc)); 616 617 return_ACPI_STATUS (AE_AML_OPERAND_TYPE); 618 } 619 goto NextOperand; 620 621 case ARGI_REGION_OR_BUFFER: /* Used by Load() only */ 622 623 /* 624 * Need an operand of type REGION or a BUFFER 625 * (which could be a resolved region field) 626 */ 627 switch (ObjDesc->Common.Type) 628 { 629 case ACPI_TYPE_BUFFER: 630 case ACPI_TYPE_REGION: 631 632 /* Valid operand */ 633 break; 634 635 default: 636 637 ACPI_ERROR ((AE_INFO, 638 "Needed [Region/Buffer], found [%s] %p", 639 AcpiUtGetObjectTypeName (ObjDesc), ObjDesc)); 640 641 return_ACPI_STATUS (AE_AML_OPERAND_TYPE); 642 } 643 goto NextOperand; 644 645 case ARGI_DATAREFOBJ: 646 647 /* Used by the Store() operator only */ 648 649 switch (ObjDesc->Common.Type) 650 { 651 case ACPI_TYPE_INTEGER: 652 case ACPI_TYPE_PACKAGE: 653 case ACPI_TYPE_STRING: 654 case ACPI_TYPE_BUFFER: 655 case ACPI_TYPE_BUFFER_FIELD: 656 case ACPI_TYPE_LOCAL_REFERENCE: 657 case ACPI_TYPE_LOCAL_REGION_FIELD: 658 case ACPI_TYPE_LOCAL_BANK_FIELD: 659 case ACPI_TYPE_LOCAL_INDEX_FIELD: 660 case ACPI_TYPE_DDB_HANDLE: 661 662 /* Valid operand */ 663 break; 664 665 default: 666 667 if (AcpiGbl_EnableInterpreterSlack) 668 { 669 /* 670 * Enable original behavior of Store(), allowing any 671 * and all objects as the source operand. The ACPI 672 * spec does not allow this, however. 673 */ 674 break; 675 } 676 677 if (TargetOp == AML_DEBUG_OP) 678 { 679 /* Allow store of any object to the Debug object */ 680 681 break; 682 } 683 684 ACPI_ERROR ((AE_INFO, 685 "Needed Integer/Buffer/String/Package/Ref/Ddb]" 686 ", found [%s] %p", 687 AcpiUtGetObjectTypeName (ObjDesc), ObjDesc)); 688 689 return_ACPI_STATUS (AE_AML_OPERAND_TYPE); 690 } 691 goto NextOperand; 692 693 default: 694 695 /* Unknown type */ 696 697 ACPI_ERROR ((AE_INFO, 698 "Internal - Unknown ARGI (required operand) type 0x%X", 699 ThisArgType)); 700 701 return_ACPI_STATUS (AE_BAD_PARAMETER); 702 } 703 704 /* 705 * Make sure that the original object was resolved to the 706 * required object type (Simple cases only). 707 */ 708 Status = AcpiExCheckObjectType ( 709 TypeNeeded, (*StackPtr)->Common.Type, *StackPtr); 710 if (ACPI_FAILURE (Status)) 711 { 712 return_ACPI_STATUS (Status); 713 } 714 715 NextOperand: 716 /* 717 * If more operands needed, decrement StackPtr to point 718 * to next operand on stack 719 */ 720 if (GET_CURRENT_ARG_TYPE (ArgTypes)) 721 { 722 StackPtr--; 723 } 724 } 725 726 ACPI_DUMP_OPERANDS (WalkState->Operands, 727 AcpiPsGetOpcodeName (Opcode), WalkState->NumOperands); 728 729 return_ACPI_STATUS (Status); 730 } 731