1 /****************************************************************************** 2 * 3 * Module Name: aslwalks.c - Miscellaneous analytical parse tree walks 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 "aslcompiler.h" 45 #include "aslcompiler.y.h" 46 #include "acparser.h" 47 #include "amlcode.h" 48 49 50 #define _COMPONENT ACPI_COMPILER 51 ACPI_MODULE_NAME ("aslwalks") 52 53 54 /* Local prototypes */ 55 56 static void 57 AnAnalyzeStoreOperator ( 58 ACPI_PARSE_OBJECT *Op); 59 60 61 /******************************************************************************* 62 * 63 * FUNCTION: AnMethodTypingWalkEnd 64 * 65 * PARAMETERS: ASL_WALK_CALLBACK 66 * 67 * RETURN: Status 68 * 69 * DESCRIPTION: Ascending callback for typing walk. Complete the method 70 * return analysis. Check methods for: 71 * 1) Initialized local variables 72 * 2) Valid arguments 73 * 3) Return types 74 * 75 ******************************************************************************/ 76 77 ACPI_STATUS 78 AnMethodTypingWalkEnd ( 79 ACPI_PARSE_OBJECT *Op, 80 UINT32 Level, 81 void *Context) 82 { 83 UINT32 ThisOpBtype; 84 85 86 switch (Op->Asl.ParseOpcode) 87 { 88 case PARSEOP_METHOD: 89 90 Op->Asl.CompileFlags |= NODE_METHOD_TYPED; 91 break; 92 93 case PARSEOP_RETURN: 94 95 if ((Op->Asl.Child) && 96 (Op->Asl.Child->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG)) 97 { 98 ThisOpBtype = AnGetBtype (Op->Asl.Child); 99 100 if ((Op->Asl.Child->Asl.ParseOpcode == PARSEOP_METHODCALL) && 101 (ThisOpBtype == (ACPI_UINT32_MAX -1))) 102 { 103 /* 104 * The called method is untyped at this time (typically a 105 * forward reference). 106 * 107 * Check for a recursive method call first. 108 */ 109 if (Op->Asl.ParentMethod != Op->Asl.Child->Asl.Node->Op) 110 { 111 /* We must type the method here */ 112 113 TrWalkParseTree (Op->Asl.Child->Asl.Node->Op, 114 ASL_WALK_VISIT_UPWARD, NULL, 115 AnMethodTypingWalkEnd, NULL); 116 117 ThisOpBtype = AnGetBtype (Op->Asl.Child); 118 } 119 } 120 121 /* Returns a value, save the value type */ 122 123 if (Op->Asl.ParentMethod) 124 { 125 Op->Asl.ParentMethod->Asl.AcpiBtype |= ThisOpBtype; 126 } 127 } 128 break; 129 130 default: 131 132 break; 133 } 134 135 return (AE_OK); 136 } 137 138 139 /******************************************************************************* 140 * 141 * FUNCTION: AnOperandTypecheckWalkEnd 142 * 143 * PARAMETERS: ASL_WALK_CALLBACK 144 * 145 * RETURN: Status 146 * 147 * DESCRIPTION: Ascending callback for analysis walk. Complete method 148 * return analysis. 149 * 150 ******************************************************************************/ 151 152 ACPI_STATUS 153 AnOperandTypecheckWalkEnd ( 154 ACPI_PARSE_OBJECT *Op, 155 UINT32 Level, 156 void *Context) 157 { 158 const ACPI_OPCODE_INFO *OpInfo; 159 UINT32 RuntimeArgTypes; 160 UINT32 RuntimeArgTypes2; 161 UINT32 RequiredBtypes; 162 UINT32 ThisNodeBtype; 163 UINT32 CommonBtypes; 164 UINT32 OpcodeClass; 165 ACPI_PARSE_OBJECT *ArgOp; 166 UINT32 ArgType; 167 168 169 switch (Op->Asl.AmlOpcode) 170 { 171 case AML_RAW_DATA_BYTE: 172 case AML_RAW_DATA_WORD: 173 case AML_RAW_DATA_DWORD: 174 case AML_RAW_DATA_QWORD: 175 case AML_RAW_DATA_BUFFER: 176 case AML_RAW_DATA_CHAIN: 177 case AML_PACKAGE_LENGTH: 178 case AML_UNASSIGNED_OPCODE: 179 case AML_DEFAULT_ARG_OP: 180 181 /* Ignore the internal (compiler-only) AML opcodes */ 182 183 return (AE_OK); 184 185 default: 186 187 break; 188 } 189 190 OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode); 191 if (!OpInfo) 192 { 193 return (AE_OK); 194 } 195 196 ArgOp = Op->Asl.Child; 197 OpcodeClass = OpInfo->Class; 198 RuntimeArgTypes = OpInfo->RuntimeArgs; 199 200 #ifdef ASL_ERROR_NAMED_OBJECT_IN_WHILE 201 /* 202 * Update 11/2008: In practice, we can't perform this check. A simple 203 * analysis is not sufficient. Also, it can cause errors when compiling 204 * disassembled code because of the way Switch operators are implemented 205 * (a While(One) loop with a named temp variable created within.) 206 */ 207 208 /* 209 * If we are creating a named object, check if we are within a while loop 210 * by checking if the parent is a WHILE op. This is a simple analysis, but 211 * probably sufficient for many cases. 212 * 213 * Allow Scope(), Buffer(), and Package(). 214 */ 215 if (((OpcodeClass == AML_CLASS_NAMED_OBJECT) && (Op->Asl.AmlOpcode != AML_SCOPE_OP)) || 216 ((OpcodeClass == AML_CLASS_CREATE) && (OpInfo->Flags & AML_NSNODE))) 217 { 218 if (Op->Asl.Parent->Asl.AmlOpcode == AML_WHILE_OP) 219 { 220 AslError (ASL_ERROR, ASL_MSG_NAMED_OBJECT_IN_WHILE, Op, NULL); 221 } 222 } 223 #endif 224 225 /* 226 * Special case for control opcodes IF/RETURN/WHILE since they 227 * have no runtime arg list (at this time) 228 */ 229 switch (Op->Asl.AmlOpcode) 230 { 231 case AML_IF_OP: 232 case AML_WHILE_OP: 233 case AML_RETURN_OP: 234 235 if (ArgOp->Asl.ParseOpcode == PARSEOP_METHODCALL) 236 { 237 /* Check for an internal method */ 238 239 if (AnIsInternalMethod (ArgOp)) 240 { 241 return (AE_OK); 242 } 243 244 /* The lone arg is a method call, check it */ 245 246 RequiredBtypes = AnMapArgTypeToBtype (ARGI_INTEGER); 247 if (Op->Asl.AmlOpcode == AML_RETURN_OP) 248 { 249 RequiredBtypes = 0xFFFFFFFF; 250 } 251 252 ThisNodeBtype = AnGetBtype (ArgOp); 253 if (ThisNodeBtype == ACPI_UINT32_MAX) 254 { 255 return (AE_OK); 256 } 257 258 AnCheckMethodReturnValue (Op, OpInfo, ArgOp, 259 RequiredBtypes, ThisNodeBtype); 260 } 261 return (AE_OK); 262 263 case AML_EXTERNAL_OP: 264 /* 265 * Not really a "runtime" opcode since it used by disassembler only. 266 * The parser will find any issues with the operands. 267 */ 268 return (AE_OK); 269 270 default: 271 272 break; 273 } 274 275 /* Ignore the non-executable opcodes */ 276 277 if (RuntimeArgTypes == ARGI_INVALID_OPCODE) 278 { 279 return (AE_OK); 280 } 281 282 /* 283 * Special handling for certain opcodes. 284 */ 285 switch (Op->Asl.AmlOpcode) 286 { 287 /* BankField has one TermArg */ 288 289 case AML_BANK_FIELD_OP: 290 291 OpcodeClass = AML_CLASS_EXECUTE; 292 ArgOp = ArgOp->Asl.Next; 293 ArgOp = ArgOp->Asl.Next; 294 break; 295 296 /* Operation Region has 2 TermArgs */ 297 298 case AML_REGION_OP: 299 300 OpcodeClass = AML_CLASS_EXECUTE; 301 ArgOp = ArgOp->Asl.Next; 302 ArgOp = ArgOp->Asl.Next; 303 break; 304 305 /* DataTableRegion has 3 TermArgs */ 306 307 case AML_DATA_REGION_OP: 308 309 OpcodeClass = AML_CLASS_EXECUTE; 310 ArgOp = ArgOp->Asl.Next; 311 break; 312 313 /* Buffers/Packages have a length that is a TermArg */ 314 315 case AML_BUFFER_OP: 316 case AML_PACKAGE_OP: 317 case AML_VAR_PACKAGE_OP: 318 319 /* If length is a constant, we are done */ 320 321 if ((ArgOp->Asl.ParseOpcode == PARSEOP_INTEGER) || 322 (ArgOp->Asl.ParseOpcode == PARSEOP_RAW_DATA)) 323 { 324 return (AE_OK); 325 } 326 break; 327 328 /* Store can write any object to the Debug object */ 329 330 case AML_STORE_OP: 331 /* 332 * If this is a Store() to the Debug object, we don't need 333 * to perform any further validation -- because a Store of 334 * any object to Debug is permitted and supported. 335 */ 336 if (ArgOp->Asl.Next->Asl.AmlOpcode == AML_DEBUG_OP) 337 { 338 return (AE_OK); 339 } 340 break; 341 342 default: 343 break; 344 } 345 346 switch (OpcodeClass) 347 { 348 case AML_CLASS_EXECUTE: 349 case AML_CLASS_CREATE: 350 case AML_CLASS_CONTROL: 351 case AML_CLASS_RETURN_VALUE: 352 353 /* Reverse the runtime argument list */ 354 355 RuntimeArgTypes2 = 0; 356 while ((ArgType = GET_CURRENT_ARG_TYPE (RuntimeArgTypes))) 357 { 358 RuntimeArgTypes2 <<= ARG_TYPE_WIDTH; 359 RuntimeArgTypes2 |= ArgType; 360 INCREMENT_ARG_LIST (RuntimeArgTypes); 361 } 362 363 /* Typecheck each argument */ 364 365 while ((ArgType = GET_CURRENT_ARG_TYPE (RuntimeArgTypes2))) 366 { 367 /* Get the required type(s) for the argument */ 368 369 RequiredBtypes = AnMapArgTypeToBtype (ArgType); 370 371 if (!ArgOp) 372 { 373 AslError (ASL_ERROR, ASL_MSG_COMPILER_INTERNAL, Op, 374 "Null ArgOp in argument loop"); 375 AslAbort (); 376 } 377 378 /* Get the actual type of the argument */ 379 380 ThisNodeBtype = AnGetBtype (ArgOp); 381 if (ThisNodeBtype == ACPI_UINT32_MAX) 382 { 383 goto NextArgument; 384 } 385 386 /* Examine the arg based on the required type of the arg */ 387 388 switch (ArgType) 389 { 390 case ARGI_TARGETREF: 391 392 if (ArgOp->Asl.ParseOpcode == PARSEOP_ZERO) 393 { 394 /* ZERO is the placeholder for "don't store result" */ 395 396 ThisNodeBtype = RequiredBtypes; 397 break; 398 } 399 400 /* Fallthrough */ 401 402 case ARGI_STORE_TARGET: 403 404 if (ArgOp->Asl.ParseOpcode == PARSEOP_INTEGER) 405 { 406 /* 407 * This is the case where an original reference to a resource 408 * descriptor field has been replaced by an (Integer) offset. 409 * These named fields are supported at compile-time only; 410 * the names are not passed to the interpreter (via the AML). 411 */ 412 if ((ArgOp->Asl.Node->Type == ACPI_TYPE_LOCAL_RESOURCE_FIELD) || 413 (ArgOp->Asl.Node->Type == ACPI_TYPE_LOCAL_RESOURCE)) 414 { 415 AslError (ASL_ERROR, ASL_MSG_RESOURCE_FIELD, 416 ArgOp, NULL); 417 } 418 else 419 { 420 AslError (ASL_ERROR, ASL_MSG_INVALID_TYPE, 421 ArgOp, NULL); 422 } 423 } 424 break; 425 426 427 #ifdef __FUTURE_IMPLEMENTATION 428 /* 429 * Possible future typechecking support 430 */ 431 case ARGI_REFERENCE: /* References */ 432 case ARGI_INTEGER_REF: 433 case ARGI_OBJECT_REF: 434 case ARGI_DEVICE_REF: 435 436 switch (ArgOp->Asl.ParseOpcode) 437 { 438 case PARSEOP_LOCAL0: 439 case PARSEOP_LOCAL1: 440 case PARSEOP_LOCAL2: 441 case PARSEOP_LOCAL3: 442 case PARSEOP_LOCAL4: 443 case PARSEOP_LOCAL5: 444 case PARSEOP_LOCAL6: 445 case PARSEOP_LOCAL7: 446 447 /* TBD: implement analysis of current value (type) of the local */ 448 /* For now, just treat any local as a typematch */ 449 450 /*ThisNodeBtype = RequiredBtypes;*/ 451 break; 452 453 case PARSEOP_ARG0: 454 case PARSEOP_ARG1: 455 case PARSEOP_ARG2: 456 case PARSEOP_ARG3: 457 case PARSEOP_ARG4: 458 case PARSEOP_ARG5: 459 case PARSEOP_ARG6: 460 461 /* Hard to analyze argument types, so we won't */ 462 /* for now. Just treat any arg as a typematch */ 463 464 /* ThisNodeBtype = RequiredBtypes; */ 465 break; 466 467 case PARSEOP_DEBUG: 468 case PARSEOP_REFOF: 469 case PARSEOP_INDEX: 470 default: 471 472 break; 473 } 474 break; 475 #endif 476 case ARGI_INTEGER: 477 default: 478 479 break; 480 } 481 482 483 /* Check for a type mismatch (required versus actual) */ 484 485 CommonBtypes = ThisNodeBtype & RequiredBtypes; 486 487 if (ArgOp->Asl.ParseOpcode == PARSEOP_METHODCALL) 488 { 489 if (AnIsInternalMethod (ArgOp)) 490 { 491 return (AE_OK); 492 } 493 494 /* Check a method call for a valid return value */ 495 496 AnCheckMethodReturnValue (Op, OpInfo, ArgOp, 497 RequiredBtypes, ThisNodeBtype); 498 } 499 500 /* 501 * Now check if the actual type(s) match at least one 502 * bit to the required type 503 */ 504 else if (!CommonBtypes) 505 { 506 /* No match -- this is a type mismatch error */ 507 508 AnFormatBtype (StringBuffer, ThisNodeBtype); 509 AnFormatBtype (StringBuffer2, RequiredBtypes); 510 511 sprintf (MsgBuffer, "[%s] found, %s operator requires [%s]", 512 StringBuffer, OpInfo->Name, StringBuffer2); 513 514 AslError (ASL_ERROR, ASL_MSG_INVALID_TYPE, 515 ArgOp, MsgBuffer); 516 } 517 518 NextArgument: 519 ArgOp = ArgOp->Asl.Next; 520 INCREMENT_ARG_LIST (RuntimeArgTypes2); 521 } 522 break; 523 524 default: 525 526 break; 527 } 528 529 return (AE_OK); 530 } 531 532 533 /******************************************************************************* 534 * 535 * FUNCTION: AnOtherSemanticAnalysisWalkBegin 536 * 537 * PARAMETERS: ASL_WALK_CALLBACK 538 * 539 * RETURN: Status 540 * 541 * DESCRIPTION: Descending callback for the analysis walk. Checks for 542 * miscellaneous issues in the code. 543 * 544 ******************************************************************************/ 545 546 ACPI_STATUS 547 AnOtherSemanticAnalysisWalkBegin ( 548 ACPI_PARSE_OBJECT *Op, 549 UINT32 Level, 550 void *Context) 551 { 552 ACPI_PARSE_OBJECT *ArgOp; 553 ACPI_PARSE_OBJECT *PrevArgOp = NULL; 554 const ACPI_OPCODE_INFO *OpInfo; 555 ACPI_NAMESPACE_NODE *Node; 556 557 558 OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode); 559 560 561 /* 562 * Determine if an execution class operator actually does something by 563 * checking if it has a target and/or the function return value is used. 564 * (Target is optional, so a standalone statement can actually do nothing.) 565 */ 566 if ((OpInfo->Class == AML_CLASS_EXECUTE) && 567 (OpInfo->Flags & AML_HAS_RETVAL) && 568 (!AnIsResultUsed (Op))) 569 { 570 if (OpInfo->Flags & AML_HAS_TARGET) 571 { 572 /* 573 * Find the target node, it is always the last child. If the target 574 * is not specified in the ASL, a default node of type Zero was 575 * created by the parser. 576 */ 577 ArgOp = Op->Asl.Child; 578 while (ArgOp->Asl.Next) 579 { 580 PrevArgOp = ArgOp; 581 ArgOp = ArgOp->Asl.Next; 582 } 583 584 /* Divide() is the only weird case, it has two targets */ 585 586 if (Op->Asl.AmlOpcode == AML_DIVIDE_OP) 587 { 588 if ((ArgOp->Asl.ParseOpcode == PARSEOP_ZERO) && 589 (PrevArgOp) && 590 (PrevArgOp->Asl.ParseOpcode == PARSEOP_ZERO)) 591 { 592 AslError (ASL_ERROR, ASL_MSG_RESULT_NOT_USED, 593 Op, Op->Asl.ExternalName); 594 } 595 } 596 597 else if (ArgOp->Asl.ParseOpcode == PARSEOP_ZERO) 598 { 599 AslError (ASL_ERROR, ASL_MSG_RESULT_NOT_USED, 600 Op, Op->Asl.ExternalName); 601 } 602 } 603 else 604 { 605 /* 606 * Has no target and the result is not used. Only a couple opcodes 607 * can have this combination. 608 */ 609 switch (Op->Asl.ParseOpcode) 610 { 611 case PARSEOP_ACQUIRE: 612 case PARSEOP_WAIT: 613 case PARSEOP_LOADTABLE: 614 615 break; 616 617 default: 618 619 AslError (ASL_ERROR, ASL_MSG_RESULT_NOT_USED, 620 Op, Op->Asl.ExternalName); 621 break; 622 } 623 } 624 } 625 626 627 /* 628 * Semantic checks for individual ASL operators 629 */ 630 switch (Op->Asl.ParseOpcode) 631 { 632 case PARSEOP_STORE: 633 634 if (Gbl_DoTypechecking) 635 { 636 AnAnalyzeStoreOperator (Op); 637 } 638 break; 639 640 641 case PARSEOP_ACQUIRE: 642 case PARSEOP_WAIT: 643 /* 644 * Emit a warning if the timeout parameter for these operators is not 645 * ACPI_WAIT_FOREVER, and the result value from the operator is not 646 * checked, meaning that a timeout could happen, but the code 647 * would not know about it. 648 */ 649 650 /* First child is the namepath, 2nd child is timeout */ 651 652 ArgOp = Op->Asl.Child; 653 ArgOp = ArgOp->Asl.Next; 654 655 /* 656 * Check for the WAIT_FOREVER case - defined by the ACPI spec to be 657 * 0xFFFF or greater 658 */ 659 if (((ArgOp->Asl.ParseOpcode == PARSEOP_WORDCONST) || 660 (ArgOp->Asl.ParseOpcode == PARSEOP_INTEGER)) && 661 (ArgOp->Asl.Value.Integer >= (UINT64) ACPI_WAIT_FOREVER)) 662 { 663 break; 664 } 665 666 /* 667 * The operation could timeout. If the return value is not used 668 * (indicates timeout occurred), issue a warning 669 */ 670 if (!AnIsResultUsed (Op)) 671 { 672 AslError (ASL_WARNING, ASL_MSG_TIMEOUT, ArgOp, 673 Op->Asl.ExternalName); 674 } 675 break; 676 677 case PARSEOP_CREATEFIELD: 678 /* 679 * Check for a zero Length (NumBits) operand. NumBits is the 3rd operand 680 */ 681 ArgOp = Op->Asl.Child; 682 ArgOp = ArgOp->Asl.Next; 683 ArgOp = ArgOp->Asl.Next; 684 685 if ((ArgOp->Asl.ParseOpcode == PARSEOP_ZERO) || 686 ((ArgOp->Asl.ParseOpcode == PARSEOP_INTEGER) && 687 (ArgOp->Asl.Value.Integer == 0))) 688 { 689 AslError (ASL_ERROR, ASL_MSG_NON_ZERO, ArgOp, NULL); 690 } 691 break; 692 693 case PARSEOP_CONNECTION: 694 /* 695 * Ensure that the referenced operation region has the correct SPACE_ID. 696 * From the grammar/parser, we know the parent is a FIELD definition. 697 */ 698 ArgOp = Op->Asl.Parent; /* Field definition */ 699 ArgOp = ArgOp->Asl.Child; /* First child is the OpRegion Name */ 700 Node = ArgOp->Asl.Node; /* OpRegion namespace node */ 701 if (!Node) 702 { 703 break; 704 } 705 706 ArgOp = Node->Op; /* OpRegion definition */ 707 ArgOp = ArgOp->Asl.Child; /* First child is the OpRegion Name */ 708 ArgOp = ArgOp->Asl.Next; /* Next peer is the SPACE_ID (what we want) */ 709 710 /* 711 * The Connection() operator is only valid for the following operation 712 * region SpaceIds: GeneralPurposeIo and GenericSerialBus. 713 */ 714 if ((ArgOp->Asl.Value.Integer != ACPI_ADR_SPACE_GPIO) && 715 (ArgOp->Asl.Value.Integer != ACPI_ADR_SPACE_GSBUS)) 716 { 717 AslError (ASL_ERROR, ASL_MSG_CONNECTION_INVALID, Op, NULL); 718 } 719 break; 720 721 case PARSEOP_FIELD: 722 /* 723 * Ensure that fields for GeneralPurposeIo and GenericSerialBus 724 * contain at least one Connection() operator 725 */ 726 ArgOp = Op->Asl.Child; /* 1st child is the OpRegion Name */ 727 Node = ArgOp->Asl.Node; /* OpRegion namespace node */ 728 if (!Node) 729 { 730 break; 731 } 732 733 ArgOp = Node->Op; /* OpRegion definition */ 734 ArgOp = ArgOp->Asl.Child; /* First child is the OpRegion Name */ 735 ArgOp = ArgOp->Asl.Next; /* Next peer is the SPACE_ID (what we want) */ 736 737 /* We are only interested in GeneralPurposeIo and GenericSerialBus */ 738 739 if ((ArgOp->Asl.Value.Integer != ACPI_ADR_SPACE_GPIO) && 740 (ArgOp->Asl.Value.Integer != ACPI_ADR_SPACE_GSBUS)) 741 { 742 break; 743 } 744 745 ArgOp = Op->Asl.Child; /* 1st child is the OpRegion Name */ 746 ArgOp = ArgOp->Asl.Next; /* AccessType */ 747 ArgOp = ArgOp->Asl.Next; /* LockRule */ 748 ArgOp = ArgOp->Asl.Next; /* UpdateRule */ 749 ArgOp = ArgOp->Asl.Next; /* Start of FieldUnitList */ 750 751 /* Walk the FieldUnitList */ 752 753 while (ArgOp) 754 { 755 if (ArgOp->Asl.ParseOpcode == PARSEOP_CONNECTION) 756 { 757 break; 758 } 759 else if (ArgOp->Asl.ParseOpcode == PARSEOP_NAMESEG) 760 { 761 AslError (ASL_ERROR, ASL_MSG_CONNECTION_MISSING, ArgOp, NULL); 762 break; 763 } 764 765 ArgOp = ArgOp->Asl.Next; 766 } 767 break; 768 769 default: 770 771 break; 772 } 773 774 return (AE_OK); 775 } 776 777 778 /******************************************************************************* 779 * 780 * FUNCTION: AnAnalyzeStoreOperator 781 * 782 * PARAMETERS: Op - Store() operator 783 * 784 * RETURN: None 785 * 786 * DESCRIPTION: Analyze a store operator. Mostly for stores to/from package 787 * objects where there are more restrictions than other data 788 * types. 789 * 790 ******************************************************************************/ 791 792 static void 793 AnAnalyzeStoreOperator ( 794 ACPI_PARSE_OBJECT *Op) 795 { 796 ACPI_NAMESPACE_NODE *SourceNode; 797 ACPI_NAMESPACE_NODE *TargetNode; 798 ACPI_PARSE_OBJECT *SourceOperandOp; 799 ACPI_PARSE_OBJECT *TargetOperandOp; 800 UINT32 SourceOperandBtype; 801 UINT32 TargetOperandBtype; 802 803 804 /* Extract the two operands for STORE */ 805 806 SourceOperandOp = Op->Asl.Child; 807 TargetOperandOp = SourceOperandOp->Asl.Next; 808 809 /* 810 * Ignore these Source operand opcodes, they cannot be typechecked, 811 * the actual result is unknown here. 812 */ 813 switch (SourceOperandOp->Asl.ParseOpcode) 814 { 815 /* For these, type of the returned value is unknown at compile time */ 816 817 case PARSEOP_DEREFOF: 818 case PARSEOP_METHODCALL: 819 case PARSEOP_STORE: 820 case PARSEOP_COPYOBJECT: 821 822 return; 823 824 case PARSEOP_INDEX: 825 case PARSEOP_REFOF: 826 827 if (!Gbl_EnableReferenceTypechecking) 828 { 829 return; 830 } 831 832 /* 833 * These opcodes always return an object reference, and thus 834 * the result can only be stored to a Local, Arg, or Debug. 835 */ 836 if (TargetOperandOp->Asl.AmlOpcode == AML_DEBUG_OP) 837 { 838 return; 839 } 840 841 if ((TargetOperandOp->Asl.AmlOpcode < AML_LOCAL0) || 842 (TargetOperandOp->Asl.AmlOpcode > AML_ARG6)) 843 { 844 AslError (ASL_ERROR, ASL_MSG_INVALID_TYPE, TargetOperandOp, 845 "Source [Reference], Target must be [Local/Arg/Debug]"); 846 } 847 return; 848 849 default: 850 break; 851 } 852 853 /* 854 * Ignore these Target operand opcodes, they cannot be typechecked 855 */ 856 switch (TargetOperandOp->Asl.ParseOpcode) 857 { 858 case PARSEOP_DEBUG: 859 case PARSEOP_DEREFOF: 860 case PARSEOP_REFOF: 861 case PARSEOP_INDEX: 862 case PARSEOP_METHODCALL: 863 864 return; 865 866 default: 867 break; 868 } 869 870 /* 871 * Ignore typecheck for External() operands of type "UnknownObj", 872 * we don't know the actual type (source or target). 873 */ 874 SourceNode = SourceOperandOp->Asl.Node; 875 if (SourceNode && 876 (SourceNode->Flags & ANOBJ_IS_EXTERNAL) && 877 (SourceNode->Type == ACPI_TYPE_ANY)) 878 { 879 return; 880 } 881 882 TargetNode = TargetOperandOp->Asl.Node; 883 if (TargetNode && 884 (TargetNode->Flags & ANOBJ_IS_EXTERNAL) && 885 (TargetNode->Type == ACPI_TYPE_ANY)) 886 { 887 return; 888 } 889 890 /* 891 * A NULL node with a namepath AML opcode indicates non-existent 892 * name. Just return, the error message is generated elsewhere. 893 */ 894 if ((!SourceNode && (SourceOperandOp->Asl.AmlOpcode == AML_INT_NAMEPATH_OP)) || 895 (!TargetNode && (TargetOperandOp->Asl.AmlOpcode == AML_INT_NAMEPATH_OP))) 896 { 897 return; 898 } 899 900 /* 901 * Simple check for source same as target via NS node. 902 * -- Could be expanded to locals and args. 903 */ 904 if (SourceNode && TargetNode) 905 { 906 if (SourceNode == TargetNode) 907 { 908 AslError (ASL_WARNING, ASL_MSG_DUPLICATE_ITEM, 909 TargetOperandOp, "Source is the same as Target"); 910 return; 911 } 912 } 913 914 /* Ignore typecheck if either source or target is a local or arg */ 915 916 if ((SourceOperandOp->Asl.AmlOpcode >= AML_LOCAL0) && 917 (SourceOperandOp->Asl.AmlOpcode <= AML_ARG6)) 918 { 919 return; /* Cannot type a local/arg at compile time */ 920 } 921 922 if ((TargetOperandOp->Asl.AmlOpcode >= AML_LOCAL0) && 923 (TargetOperandOp->Asl.AmlOpcode <= AML_ARG6)) 924 { 925 return; /* Cannot type a local/arg at compile time */ 926 } 927 928 /* 929 * Package objects are a special case because they cannot by implicitly 930 * converted to/from anything. Check for these two illegal cases: 931 * 932 * Store (non-package, package) 933 * Store (package, non-package) 934 */ 935 SourceOperandBtype = AnGetBtype (SourceOperandOp); 936 TargetOperandBtype = AnGetBtype (TargetOperandOp); 937 938 /* Check source first for (package, non-package) case */ 939 940 if (SourceOperandBtype & ACPI_BTYPE_PACKAGE) 941 { 942 /* If Source is PACKAGE-->Target must be PACKAGE */ 943 944 if (!(TargetOperandBtype & ACPI_BTYPE_PACKAGE)) 945 { 946 AslError (ASL_ERROR, ASL_MSG_INVALID_TYPE, TargetOperandOp, 947 "Source is [Package], Target must be a package also"); 948 } 949 } 950 951 /* Else check target for (non-package, package) case */ 952 953 else if (TargetOperandBtype & ACPI_BTYPE_PACKAGE) 954 { 955 /* If Target is PACKAGE, Source must be PACKAGE */ 956 957 if (!(SourceOperandBtype & ACPI_BTYPE_PACKAGE)) 958 { 959 AslError (ASL_ERROR, ASL_MSG_INVALID_TYPE, SourceOperandOp, 960 "Target is [Package], Source must be a package also"); 961 } 962 } 963 } 964