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