1 /****************************************************************************** 2 * 3 * Module Name: exresop - AML Interpreter operand/object resolution 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2013, 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 #define __EXRESOP_C__ 45 46 #include "acpi.h" 47 #include "accommon.h" 48 #include "amlcode.h" 49 #include "acparser.h" 50 #include "acinterp.h" 51 #include "acnamesp.h" 52 53 54 #define _COMPONENT ACPI_EXECUTER 55 ACPI_MODULE_NAME ("exresop") 56 57 /* Local prototypes */ 58 59 static ACPI_STATUS 60 AcpiExCheckObjectType ( 61 ACPI_OBJECT_TYPE TypeNeeded, 62 ACPI_OBJECT_TYPE ThisType, 63 void *Object); 64 65 66 /******************************************************************************* 67 * 68 * FUNCTION: AcpiExCheckObjectType 69 * 70 * PARAMETERS: TypeNeeded Object type needed 71 * ThisType Actual object type 72 * Object Object pointer 73 * 74 * RETURN: Status 75 * 76 * DESCRIPTION: Check required type against actual type 77 * 78 ******************************************************************************/ 79 80 static ACPI_STATUS 81 AcpiExCheckObjectType ( 82 ACPI_OBJECT_TYPE TypeNeeded, 83 ACPI_OBJECT_TYPE ThisType, 84 void *Object) 85 { 86 ACPI_FUNCTION_ENTRY (); 87 88 89 if (TypeNeeded == ACPI_TYPE_ANY) 90 { 91 /* All types OK, so we don't perform any typechecks */ 92 93 return (AE_OK); 94 } 95 96 if (TypeNeeded == ACPI_TYPE_LOCAL_REFERENCE) 97 { 98 /* 99 * Allow the AML "Constant" opcodes (Zero, One, etc.) to be reference 100 * objects and thus allow them to be targets. (As per the ACPI 101 * specification, a store to a constant is a noop.) 102 */ 103 if ((ThisType == ACPI_TYPE_INTEGER) && 104 (((ACPI_OPERAND_OBJECT *) Object)->Common.Flags & AOPOBJ_AML_CONSTANT)) 105 { 106 return (AE_OK); 107 } 108 } 109 110 if (TypeNeeded != ThisType) 111 { 112 ACPI_ERROR ((AE_INFO, 113 "Needed type [%s], found [%s] %p", 114 AcpiUtGetTypeName (TypeNeeded), 115 AcpiUtGetTypeName (ThisType), Object)); 116 117 return (AE_AML_OPERAND_TYPE); 118 } 119 120 return (AE_OK); 121 } 122 123 124 /******************************************************************************* 125 * 126 * FUNCTION: AcpiExResolveOperands 127 * 128 * PARAMETERS: Opcode - Opcode being interpreted 129 * StackPtr - Pointer to the operand stack to be 130 * resolved 131 * WalkState - Current state 132 * 133 * RETURN: Status 134 * 135 * DESCRIPTION: Convert multiple input operands to the types required by the 136 * target operator. 137 * 138 * Each 5-bit group in ArgTypes represents one required 139 * operand and indicates the required Type. The corresponding operand 140 * will be converted to the required type if possible, otherwise we 141 * abort with an exception. 142 * 143 ******************************************************************************/ 144 145 ACPI_STATUS 146 AcpiExResolveOperands ( 147 UINT16 Opcode, 148 ACPI_OPERAND_OBJECT **StackPtr, 149 ACPI_WALK_STATE *WalkState) 150 { 151 ACPI_OPERAND_OBJECT *ObjDesc; 152 ACPI_STATUS Status = AE_OK; 153 UINT8 ObjectType; 154 UINT32 ArgTypes; 155 const ACPI_OPCODE_INFO *OpInfo; 156 UINT32 ThisArgType; 157 ACPI_OBJECT_TYPE TypeNeeded; 158 UINT16 TargetOp = 0; 159 160 161 ACPI_FUNCTION_TRACE_U32 (ExResolveOperands, Opcode); 162 163 164 OpInfo = AcpiPsGetOpcodeInfo (Opcode); 165 if (OpInfo->Class == AML_CLASS_UNKNOWN) 166 { 167 return_ACPI_STATUS (AE_AML_BAD_OPCODE); 168 } 169 170 ArgTypes = OpInfo->RuntimeArgs; 171 if (ArgTypes == ARGI_INVALID_OPCODE) 172 { 173 ACPI_ERROR ((AE_INFO, "Unknown AML opcode 0x%X", 174 Opcode)); 175 176 return_ACPI_STATUS (AE_AML_INTERNAL); 177 } 178 179 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, 180 "Opcode %X [%s] RequiredOperandTypes=%8.8X\n", 181 Opcode, OpInfo->Name, ArgTypes)); 182 183 /* 184 * Normal exit is with (ArgTypes == 0) at end of argument list. 185 * Function will return an exception from within the loop upon 186 * finding an entry which is not (or cannot be converted 187 * to) the required type; if stack underflows; or upon 188 * finding a NULL stack entry (which should not happen). 189 */ 190 while (GET_CURRENT_ARG_TYPE (ArgTypes)) 191 { 192 if (!StackPtr || !*StackPtr) 193 { 194 ACPI_ERROR ((AE_INFO, "Null stack entry at %p", 195 StackPtr)); 196 197 return_ACPI_STATUS (AE_AML_INTERNAL); 198 } 199 200 /* Extract useful items */ 201 202 ObjDesc = *StackPtr; 203 204 /* Decode the descriptor type */ 205 206 switch (ACPI_GET_DESCRIPTOR_TYPE (ObjDesc)) 207 { 208 case ACPI_DESC_TYPE_NAMED: 209 210 /* Namespace Node */ 211 212 ObjectType = ((ACPI_NAMESPACE_NODE *) ObjDesc)->Type; 213 214 /* 215 * Resolve an alias object. The construction of these objects 216 * guarantees that there is only one level of alias indirection; 217 * thus, the attached object is always the aliased namespace node 218 */ 219 if (ObjectType == ACPI_TYPE_LOCAL_ALIAS) 220 { 221 ObjDesc = AcpiNsGetAttachedObject ((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) == ACPI_DESC_TYPE_OPERAND) && 303 (ObjDesc->Common.Type == ACPI_TYPE_STRING)) 304 { 305 /* 306 * String found - the string references a named object and 307 * must be resolved to a node 308 */ 309 goto NextOperand; 310 } 311 312 /* 313 * Else not a string - fall through to the normal Reference 314 * case below 315 */ 316 /*lint -fallthrough */ 317 318 case ARGI_REFERENCE: /* References: */ 319 case ARGI_INTEGER_REF: 320 case ARGI_OBJECT_REF: 321 case ARGI_DEVICE_REF: 322 case ARGI_TARGETREF: /* Allows implicit conversion rules before store */ 323 case ARGI_FIXED_TARGET: /* No implicit conversion before store to target */ 324 case ARGI_SIMPLE_TARGET: /* Name, Local, or Arg - no implicit conversion */ 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 }