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