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