1 2 /****************************************************************************** 3 * 4 * Module Name: aslanalyze.c - check for semantic errors 5 * 6 *****************************************************************************/ 7 8 /****************************************************************************** 9 * 10 * 1. Copyright Notice 11 * 12 * Some or all of this work - Copyright (c) 1999 - 2009, Intel Corp. 13 * All rights reserved. 14 * 15 * 2. License 16 * 17 * 2.1. This is your license from Intel Corp. under its intellectual property 18 * rights. You may have additional license terms from the party that provided 19 * you this software, covering your right to use that party's intellectual 20 * property rights. 21 * 22 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 23 * copy of the source code appearing in this file ("Covered Code") an 24 * irrevocable, perpetual, worldwide license under Intel's copyrights in the 25 * base code distributed originally by Intel ("Original Intel Code") to copy, 26 * make derivatives, distribute, use and display any portion of the Covered 27 * Code in any form, with the right to sublicense such rights; and 28 * 29 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 30 * license (with the right to sublicense), under only those claims of Intel 31 * patents that are infringed by the Original Intel Code, to make, use, sell, 32 * offer to sell, and import the Covered Code and derivative works thereof 33 * solely to the minimum extent necessary to exercise the above copyright 34 * license, and in no event shall the patent license extend to any additions 35 * to or modifications of the Original Intel Code. No other license or right 36 * is granted directly or by implication, estoppel or otherwise; 37 * 38 * The above copyright and patent license is granted only if the following 39 * conditions are met: 40 * 41 * 3. Conditions 42 * 43 * 3.1. Redistribution of Source with Rights to Further Distribute Source. 44 * Redistribution of source code of any substantial portion of the Covered 45 * Code or modification with rights to further distribute source must include 46 * the above Copyright Notice, the above License, this list of Conditions, 47 * and the following Disclaimer and Export Compliance provision. In addition, 48 * Licensee must cause all Covered Code to which Licensee contributes to 49 * contain a file documenting the changes Licensee made to create that Covered 50 * Code and the date of any change. Licensee must include in that file the 51 * documentation of any changes made by any predecessor Licensee. Licensee 52 * must include a prominent statement that the modification is derived, 53 * directly or indirectly, from Original Intel Code. 54 * 55 * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 56 * Redistribution of source code of any substantial portion of the Covered 57 * Code or modification without rights to further distribute source must 58 * include the following Disclaimer and Export Compliance provision in the 59 * documentation and/or other materials provided with distribution. In 60 * addition, Licensee may not authorize further sublicense of source of any 61 * portion of the Covered Code, and must include terms to the effect that the 62 * license from Licensee to its licensee is limited to the intellectual 63 * property embodied in the software Licensee provides to its licensee, and 64 * not to intellectual property embodied in modifications its licensee may 65 * make. 66 * 67 * 3.3. Redistribution of Executable. Redistribution in executable form of any 68 * substantial portion of the Covered Code or modification must reproduce the 69 * above Copyright Notice, and the following Disclaimer and Export Compliance 70 * provision in the documentation and/or other materials provided with the 71 * distribution. 72 * 73 * 3.4. Intel retains all right, title, and interest in and to the Original 74 * Intel Code. 75 * 76 * 3.5. Neither the name Intel nor any other trademark owned or controlled by 77 * Intel shall be used in advertising or otherwise to promote the sale, use or 78 * other dealings in products derived from or relating to the Covered Code 79 * without prior written authorization from Intel. 80 * 81 * 4. Disclaimer and Export Compliance 82 * 83 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 84 * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 85 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 86 * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 87 * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 88 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 89 * PARTICULAR PURPOSE. 90 * 91 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 92 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 93 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 94 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 95 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 96 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 97 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 98 * LIMITED REMEDY. 99 * 100 * 4.3. Licensee shall not export, either directly or indirectly, any of this 101 * software or system incorporating such software without first obtaining any 102 * required license or other approval from the U. S. Department of Commerce or 103 * any other agency or department of the United States Government. In the 104 * event Licensee exports any such software from the United States or 105 * re-exports any such software from a foreign destination, Licensee shall 106 * ensure that the distribution and export/re-export of the software is in 107 * compliance with all laws, regulations, orders, or other restrictions of the 108 * U.S. Export Administration Regulations. Licensee agrees that neither it nor 109 * any of its subsidiaries will export/re-export any technical data, process, 110 * software, or service, directly or indirectly, to any country for which the 111 * United States government or any agency thereof requires an export license, 112 * other governmental approval, or letter of assurance, without first obtaining 113 * such license, approval or letter. 114 * 115 *****************************************************************************/ 116 117 118 #include <contrib/dev/acpica/compiler/aslcompiler.h> 119 #include "aslcompiler.y.h" 120 #include <contrib/dev/acpica/include/acparser.h> 121 #include <contrib/dev/acpica/include/amlcode.h> 122 123 #define _COMPONENT ACPI_COMPILER 124 ACPI_MODULE_NAME ("aslanalyze") 125 126 /* Local prototypes */ 127 128 static UINT32 129 AnMapArgTypeToBtype ( 130 UINT32 ArgType); 131 132 static UINT32 133 AnMapEtypeToBtype ( 134 UINT32 Etype); 135 136 static void 137 AnFormatBtype ( 138 char *Buffer, 139 UINT32 Btype); 140 141 static UINT32 142 AnGetBtype ( 143 ACPI_PARSE_OBJECT *Op); 144 145 static UINT32 146 AnCheckForReservedName ( 147 ACPI_PARSE_OBJECT *Op, 148 char *Name); 149 150 static void 151 AnCheckForReservedMethod ( 152 ACPI_PARSE_OBJECT *Op, 153 ASL_METHOD_INFO *MethodInfo); 154 155 static UINT32 156 AnMapObjTypeToBtype ( 157 ACPI_PARSE_OBJECT *Op); 158 159 static BOOLEAN 160 AnLastStatementIsReturn ( 161 ACPI_PARSE_OBJECT *Op); 162 163 static void 164 AnCheckMethodReturnValue ( 165 ACPI_PARSE_OBJECT *Op, 166 const ACPI_OPCODE_INFO *OpInfo, 167 ACPI_PARSE_OBJECT *ArgOp, 168 UINT32 RequiredBtypes, 169 UINT32 ThisNodeBtype); 170 171 static BOOLEAN 172 AnIsInternalMethod ( 173 ACPI_PARSE_OBJECT *Op); 174 175 static UINT32 176 AnGetInternalMethodReturnType ( 177 ACPI_PARSE_OBJECT *Op); 178 179 BOOLEAN 180 AnIsResultUsed ( 181 ACPI_PARSE_OBJECT *Op); 182 183 184 /******************************************************************************* 185 * 186 * FUNCTION: AnIsInternalMethod 187 * 188 * PARAMETERS: Op - Current op 189 * 190 * RETURN: Boolean 191 * 192 * DESCRIPTION: Check for an internal control method. 193 * 194 ******************************************************************************/ 195 196 static BOOLEAN 197 AnIsInternalMethod ( 198 ACPI_PARSE_OBJECT *Op) 199 { 200 201 if ((!ACPI_STRCMP (Op->Asl.ExternalName, "\\_OSI")) || 202 (!ACPI_STRCMP (Op->Asl.ExternalName, "_OSI"))) 203 { 204 return (TRUE); 205 } 206 207 return (FALSE); 208 } 209 210 211 /******************************************************************************* 212 * 213 * FUNCTION: AnGetInternalMethodReturnType 214 * 215 * PARAMETERS: Op - Current op 216 * 217 * RETURN: Btype 218 * 219 * DESCRIPTION: Get the return type of an internal method 220 * 221 ******************************************************************************/ 222 223 static UINT32 224 AnGetInternalMethodReturnType ( 225 ACPI_PARSE_OBJECT *Op) 226 { 227 228 if ((!ACPI_STRCMP (Op->Asl.ExternalName, "\\_OSI")) || 229 (!ACPI_STRCMP (Op->Asl.ExternalName, "_OSI"))) 230 { 231 return (ACPI_BTYPE_STRING); 232 } 233 234 return (0); 235 } 236 237 238 /******************************************************************************* 239 * 240 * FUNCTION: AnMapArgTypeToBtype 241 * 242 * PARAMETERS: ArgType - The ARGI required type(s) for this argument, 243 * from the opcode info table 244 * 245 * RETURN: The corresponding Bit-encoded types 246 * 247 * DESCRIPTION: Convert an encoded ARGI required argument type code into a 248 * bitfield type code. Implements the implicit source conversion 249 * rules. 250 * 251 ******************************************************************************/ 252 253 static UINT32 254 AnMapArgTypeToBtype ( 255 UINT32 ArgType) 256 { 257 258 switch (ArgType) 259 { 260 261 /* Simple types */ 262 263 case ARGI_ANYTYPE: 264 return (ACPI_BTYPE_OBJECTS_AND_REFS); 265 266 case ARGI_PACKAGE: 267 return (ACPI_BTYPE_PACKAGE); 268 269 case ARGI_EVENT: 270 return (ACPI_BTYPE_EVENT); 271 272 case ARGI_MUTEX: 273 return (ACPI_BTYPE_MUTEX); 274 275 case ARGI_DDBHANDLE: 276 /* 277 * DDBHandleObject := SuperName 278 * ACPI_BTYPE_REFERENCE: Index reference as parameter of Load/Unload 279 */ 280 return (ACPI_BTYPE_DDB_HANDLE | ACPI_BTYPE_REFERENCE); 281 282 /* Interchangeable types */ 283 /* 284 * Source conversion rules: 285 * Integer, String, and Buffer are all interchangeable 286 */ 287 case ARGI_INTEGER: 288 case ARGI_STRING: 289 case ARGI_BUFFER: 290 case ARGI_BUFFER_OR_STRING: 291 case ARGI_COMPUTEDATA: 292 return (ACPI_BTYPE_COMPUTE_DATA); 293 294 /* References */ 295 296 case ARGI_INTEGER_REF: 297 return (ACPI_BTYPE_INTEGER); 298 299 case ARGI_OBJECT_REF: 300 return (ACPI_BTYPE_ALL_OBJECTS); 301 302 case ARGI_DEVICE_REF: 303 return (ACPI_BTYPE_DEVICE_OBJECTS); 304 305 case ARGI_REFERENCE: 306 return (ACPI_BTYPE_REFERENCE); 307 308 case ARGI_TARGETREF: 309 case ARGI_FIXED_TARGET: 310 case ARGI_SIMPLE_TARGET: 311 return (ACPI_BTYPE_OBJECTS_AND_REFS); 312 313 /* Complex types */ 314 315 case ARGI_DATAOBJECT: 316 317 /* 318 * Buffer, string, package or reference to a Op - 319 * Used only by SizeOf operator 320 */ 321 return (ACPI_BTYPE_STRING | ACPI_BTYPE_BUFFER | 322 ACPI_BTYPE_PACKAGE | ACPI_BTYPE_REFERENCE); 323 324 case ARGI_COMPLEXOBJ: 325 326 /* Buffer, String, or package */ 327 328 return (ACPI_BTYPE_STRING | ACPI_BTYPE_BUFFER | ACPI_BTYPE_PACKAGE); 329 330 case ARGI_REF_OR_STRING: 331 return (ACPI_BTYPE_STRING | ACPI_BTYPE_REFERENCE); 332 333 case ARGI_REGION_OR_BUFFER: 334 335 /* Used by Load() only. Allow buffers in addition to regions/fields */ 336 337 return (ACPI_BTYPE_REGION | ACPI_BTYPE_BUFFER | ACPI_BTYPE_FIELD_UNIT); 338 339 case ARGI_DATAREFOBJ: 340 return (ACPI_BTYPE_INTEGER |ACPI_BTYPE_STRING | ACPI_BTYPE_BUFFER | 341 ACPI_BTYPE_PACKAGE | ACPI_BTYPE_REFERENCE | ACPI_BTYPE_DDB_HANDLE); 342 343 default: 344 break; 345 } 346 347 return (ACPI_BTYPE_OBJECTS_AND_REFS); 348 } 349 350 351 /******************************************************************************* 352 * 353 * FUNCTION: AnMapEtypeToBtype 354 * 355 * PARAMETERS: Etype - Encoded ACPI Type 356 * 357 * RETURN: Btype corresponding to the Etype 358 * 359 * DESCRIPTION: Convert an encoded ACPI type to a bitfield type applying the 360 * operand conversion rules. In other words, returns the type(s) 361 * this Etype is implicitly converted to during interpretation. 362 * 363 ******************************************************************************/ 364 365 static UINT32 366 AnMapEtypeToBtype ( 367 UINT32 Etype) 368 { 369 370 371 if (Etype == ACPI_TYPE_ANY) 372 { 373 return ACPI_BTYPE_OBJECTS_AND_REFS; 374 } 375 376 /* Try the standard ACPI data types */ 377 378 if (Etype <= ACPI_TYPE_EXTERNAL_MAX) 379 { 380 /* 381 * This switch statement implements the allowed operand conversion 382 * rules as per the "ASL Data Types" section of the ACPI 383 * specification. 384 */ 385 switch (Etype) 386 { 387 case ACPI_TYPE_INTEGER: 388 return (ACPI_BTYPE_COMPUTE_DATA | ACPI_BTYPE_DDB_HANDLE); 389 390 case ACPI_TYPE_STRING: 391 case ACPI_TYPE_BUFFER: 392 return (ACPI_BTYPE_COMPUTE_DATA); 393 394 case ACPI_TYPE_PACKAGE: 395 return (ACPI_BTYPE_PACKAGE); 396 397 case ACPI_TYPE_FIELD_UNIT: 398 return (ACPI_BTYPE_COMPUTE_DATA | ACPI_BTYPE_FIELD_UNIT); 399 400 case ACPI_TYPE_BUFFER_FIELD: 401 return (ACPI_BTYPE_COMPUTE_DATA | ACPI_BTYPE_BUFFER_FIELD); 402 403 case ACPI_TYPE_DDB_HANDLE: 404 return (ACPI_BTYPE_INTEGER | ACPI_BTYPE_DDB_HANDLE); 405 406 case ACPI_BTYPE_DEBUG_OBJECT: 407 408 /* Cannot be used as a source operand */ 409 410 return (0); 411 412 default: 413 return (1 << (Etype - 1)); 414 } 415 } 416 417 /* Try the internal data types */ 418 419 switch (Etype) 420 { 421 case ACPI_TYPE_LOCAL_REGION_FIELD: 422 case ACPI_TYPE_LOCAL_BANK_FIELD: 423 case ACPI_TYPE_LOCAL_INDEX_FIELD: 424 425 /* Named fields can be either Integer/Buffer/String */ 426 427 return (ACPI_BTYPE_COMPUTE_DATA | ACPI_BTYPE_FIELD_UNIT); 428 429 case ACPI_TYPE_LOCAL_ALIAS: 430 431 return (ACPI_BTYPE_INTEGER); 432 433 434 case ACPI_TYPE_LOCAL_RESOURCE: 435 case ACPI_TYPE_LOCAL_RESOURCE_FIELD: 436 437 return (ACPI_BTYPE_REFERENCE); 438 439 default: 440 printf ("Unhandled encoded type: %X\n", Etype); 441 return (0); 442 } 443 } 444 445 446 /******************************************************************************* 447 * 448 * FUNCTION: AnFormatBtype 449 * 450 * PARAMETERS: Btype - Bitfield of ACPI types 451 * Buffer - Where to put the ascii string 452 * 453 * RETURN: None. 454 * 455 * DESCRIPTION: Convert a Btype to a string of ACPI types 456 * 457 ******************************************************************************/ 458 459 static void 460 AnFormatBtype ( 461 char *Buffer, 462 UINT32 Btype) 463 { 464 UINT32 Type; 465 BOOLEAN First = TRUE; 466 467 468 *Buffer = 0; 469 470 if (Btype == 0) 471 { 472 strcat (Buffer, "NoReturnValue"); 473 return; 474 } 475 476 for (Type = 1; Type <= ACPI_TYPE_EXTERNAL_MAX; Type++) 477 { 478 if (Btype & 0x00000001) 479 { 480 if (!First) 481 { 482 strcat (Buffer, "|"); 483 } 484 First = FALSE; 485 strcat (Buffer, AcpiUtGetTypeName (Type)); 486 } 487 Btype >>= 1; 488 } 489 490 if (Btype & 0x00000001) 491 { 492 if (!First) 493 { 494 strcat (Buffer, "|"); 495 } 496 First = FALSE; 497 strcat (Buffer, "Reference"); 498 } 499 500 Btype >>= 1; 501 if (Btype & 0x00000001) 502 { 503 if (!First) 504 { 505 strcat (Buffer, "|"); 506 } 507 First = FALSE; 508 strcat (Buffer, "Resource"); 509 } 510 } 511 512 513 /******************************************************************************* 514 * 515 * FUNCTION: AnGetBtype 516 * 517 * PARAMETERS: Op - Parse node whose type will be returned. 518 * 519 * RETURN: The Btype associated with the Op. 520 * 521 * DESCRIPTION: Get the (bitfield) ACPI type associated with the parse node. 522 * Handles the case where the node is a name or method call and 523 * the actual type must be obtained from the namespace node. 524 * 525 ******************************************************************************/ 526 527 static UINT32 528 AnGetBtype ( 529 ACPI_PARSE_OBJECT *Op) 530 { 531 ACPI_NAMESPACE_NODE *Node; 532 ACPI_PARSE_OBJECT *ReferencedNode; 533 UINT32 ThisNodeBtype = 0; 534 535 536 if ((Op->Asl.ParseOpcode == PARSEOP_NAMESEG) || 537 (Op->Asl.ParseOpcode == PARSEOP_NAMESTRING) || 538 (Op->Asl.ParseOpcode == PARSEOP_METHODCALL)) 539 { 540 Node = Op->Asl.Node; 541 if (!Node) 542 { 543 DbgPrint (ASL_DEBUG_OUTPUT, 544 "No attached Nsnode: [%s] at line %d name [%s], ignoring typecheck\n", 545 Op->Asl.ParseOpName, Op->Asl.LineNumber, 546 Op->Asl.ExternalName); 547 return ACPI_UINT32_MAX; 548 } 549 550 ThisNodeBtype = AnMapEtypeToBtype (Node->Type); 551 if (!ThisNodeBtype) 552 { 553 AslError (ASL_ERROR, ASL_MSG_COMPILER_INTERNAL, Op, 554 "could not map type"); 555 } 556 557 /* 558 * Since it was a named reference, enable the 559 * reference bit also 560 */ 561 ThisNodeBtype |= ACPI_BTYPE_REFERENCE; 562 563 if (Op->Asl.ParseOpcode == PARSEOP_METHODCALL) 564 { 565 ReferencedNode = Node->Op; 566 if (!ReferencedNode) 567 { 568 /* Check for an internal method */ 569 570 if (AnIsInternalMethod (Op)) 571 { 572 return (AnGetInternalMethodReturnType (Op)); 573 } 574 575 AslError (ASL_ERROR, ASL_MSG_COMPILER_INTERNAL, Op, 576 "null Op pointer"); 577 return ACPI_UINT32_MAX; 578 } 579 580 if (ReferencedNode->Asl.CompileFlags & NODE_METHOD_TYPED) 581 { 582 ThisNodeBtype = ReferencedNode->Asl.AcpiBtype; 583 } 584 else 585 { 586 return (ACPI_UINT32_MAX -1); 587 } 588 } 589 } 590 else 591 { 592 ThisNodeBtype = Op->Asl.AcpiBtype; 593 } 594 595 return (ThisNodeBtype); 596 } 597 598 599 /******************************************************************************* 600 * 601 * FUNCTION: AnCheckForReservedName 602 * 603 * PARAMETERS: Op - A parse node 604 * Name - NameSeg to check 605 * 606 * RETURN: None 607 * 608 * DESCRIPTION: Check a NameSeg against the reserved list. 609 * 610 ******************************************************************************/ 611 612 static UINT32 613 AnCheckForReservedName ( 614 ACPI_PARSE_OBJECT *Op, 615 char *Name) 616 { 617 UINT32 i; 618 619 620 if (Name[0] == 0) 621 { 622 AcpiOsPrintf ("Found a null name, external = %s\n", 623 Op->Asl.ExternalName); 624 } 625 626 /* All reserved names are prefixed with a single underscore */ 627 628 if (Name[0] != '_') 629 { 630 return (ACPI_NOT_RESERVED_NAME); 631 } 632 633 /* Check for a standard reserved method name */ 634 635 for (i = 0; ReservedMethods[i].Name; i++) 636 { 637 if (ACPI_COMPARE_NAME (Name, ReservedMethods[i].Name)) 638 { 639 if (ReservedMethods[i].Flags & ASL_RSVD_SCOPE) 640 { 641 AslError (ASL_ERROR, ASL_MSG_RESERVED_WORD, Op, 642 Op->Asl.ExternalName); 643 return (ACPI_PREDEFINED_NAME); 644 } 645 else if (ReservedMethods[i].Flags & ASL_RSVD_RESOURCE_NAME) 646 { 647 AslError (ASL_ERROR, ASL_MSG_RESERVED_WORD, Op, 648 Op->Asl.ExternalName); 649 return (ACPI_PREDEFINED_NAME); 650 } 651 652 /* Return index into reserved array */ 653 654 return i; 655 } 656 } 657 658 /* 659 * Now check for the "special" reserved names -- 660 * GPE: _Lxx 661 * GPE: _Exx 662 * EC: _Qxx 663 */ 664 if ((Name[1] == 'L') || 665 (Name[1] == 'E') || 666 (Name[1] == 'Q')) 667 { 668 /* The next two characters must be hex digits */ 669 670 if ((isxdigit (Name[2])) && 671 (isxdigit (Name[3]))) 672 { 673 return (ACPI_EVENT_RESERVED_NAME); 674 } 675 } 676 677 678 /* Check for the names reserved for the compiler itself: _T_x */ 679 680 else if ((Op->Asl.ExternalName[1] == 'T') && 681 (Op->Asl.ExternalName[2] == '_')) 682 { 683 /* Ignore if actually emitted by the compiler */ 684 685 if (Op->Asl.CompileFlags & NODE_COMPILER_EMITTED) 686 { 687 return (ACPI_NOT_RESERVED_NAME); 688 } 689 690 /* 691 * Was not actually emitted by the compiler. This is a special case, 692 * however. If the ASL code being compiled was the result of a 693 * dissasembly, it may possibly contain valid compiler-emitted names 694 * of the form "_T_x". We don't want to issue an error or even a 695 * warning and force the user to manually change the names. So, we 696 * will issue a remark instead. 697 */ 698 AslError (ASL_REMARK, ASL_MSG_COMPILER_RESERVED, Op, Op->Asl.ExternalName); 699 return (ACPI_COMPILER_RESERVED_NAME); 700 } 701 702 /* 703 * The name didn't match any of the known reserved names. Flag it as a 704 * warning, since the entire namespace starting with an underscore is 705 * reserved by the ACPI spec. 706 */ 707 AslError (ASL_WARNING, ASL_MSG_UNKNOWN_RESERVED_NAME, Op, 708 Op->Asl.ExternalName); 709 710 return (ACPI_NOT_RESERVED_NAME); 711 } 712 713 714 /******************************************************************************* 715 * 716 * FUNCTION: AnCheckForReservedMethod 717 * 718 * PARAMETERS: Op - A parse node of type "METHOD". 719 * MethodInfo - Saved info about this method 720 * 721 * RETURN: None 722 * 723 * DESCRIPTION: If method is a reserved name, check that the number of arguments 724 * and the return type (returns a value or not) is correct. 725 * 726 ******************************************************************************/ 727 728 static void 729 AnCheckForReservedMethod ( 730 ACPI_PARSE_OBJECT *Op, 731 ASL_METHOD_INFO *MethodInfo) 732 { 733 UINT32 Index; 734 UINT32 RequiredArgsCurrent; 735 UINT32 RequiredArgsOld; 736 737 738 /* Check for a match against the reserved name list */ 739 740 Index = AnCheckForReservedName (Op, Op->Asl.NameSeg); 741 742 switch (Index) 743 { 744 case ACPI_NOT_RESERVED_NAME: 745 case ACPI_PREDEFINED_NAME: 746 case ACPI_COMPILER_RESERVED_NAME: 747 748 /* Just return, nothing to do */ 749 break; 750 751 752 case ACPI_EVENT_RESERVED_NAME: 753 754 Gbl_ReservedMethods++; 755 756 /* NumArguments must be zero for all _Lxx, _Exx, and _Qxx methods */ 757 758 if (MethodInfo->NumArguments != 0) 759 { 760 sprintf (MsgBuffer, "%s requires %d", 761 Op->Asl.ExternalName, 0); 762 763 AslError (ASL_WARNING, ASL_MSG_RESERVED_ARG_COUNT_HI, Op, MsgBuffer); 764 } 765 break; 766 767 768 default: 769 770 Gbl_ReservedMethods++; 771 772 /* 773 * Matched a reserved method name 774 * 775 * Validate the ASL-defined argument count. Allow two different legal 776 * arg counts. 777 */ 778 RequiredArgsCurrent = ReservedMethods[Index].NumArguments & 0x0F; 779 RequiredArgsOld = ReservedMethods[Index].NumArguments >> 4; 780 781 if ((MethodInfo->NumArguments != RequiredArgsCurrent) && 782 (MethodInfo->NumArguments != RequiredArgsOld)) 783 { 784 sprintf (MsgBuffer, "%s requires %d", 785 ReservedMethods[Index].Name, 786 RequiredArgsCurrent); 787 788 if (MethodInfo->NumArguments > RequiredArgsCurrent) 789 { 790 AslError (ASL_WARNING, ASL_MSG_RESERVED_ARG_COUNT_HI, Op, 791 MsgBuffer); 792 } 793 else 794 { 795 AslError (ASL_WARNING, ASL_MSG_RESERVED_ARG_COUNT_LO, Op, 796 MsgBuffer); 797 } 798 } 799 800 if (MethodInfo->NumReturnNoValue && 801 ReservedMethods[Index].Flags & ASL_RSVD_RETURN_VALUE) 802 { 803 sprintf (MsgBuffer, "%s", ReservedMethods[Index].Name); 804 805 AslError (ASL_WARNING, ASL_MSG_RESERVED_RETURN_VALUE, Op, MsgBuffer); 806 } 807 break; 808 } 809 } 810 811 812 /******************************************************************************* 813 * 814 * FUNCTION: AnMapObjTypeToBtype 815 * 816 * PARAMETERS: Op - A parse node 817 * 818 * RETURN: A Btype 819 * 820 * DESCRIPTION: Map object to the associated "Btype" 821 * 822 ******************************************************************************/ 823 824 static UINT32 825 AnMapObjTypeToBtype ( 826 ACPI_PARSE_OBJECT *Op) 827 { 828 829 switch (Op->Asl.ParseOpcode) 830 { 831 case PARSEOP_OBJECTTYPE_BFF: /* "BuffFieldObj" */ 832 return (ACPI_BTYPE_BUFFER_FIELD); 833 834 case PARSEOP_OBJECTTYPE_BUF: /* "BuffObj" */ 835 return (ACPI_BTYPE_BUFFER); 836 837 case PARSEOP_OBJECTTYPE_DDB: /* "DDBHandleObj" */ 838 return (ACPI_BTYPE_DDB_HANDLE); 839 840 case PARSEOP_OBJECTTYPE_DEV: /* "DeviceObj" */ 841 return (ACPI_BTYPE_DEVICE); 842 843 case PARSEOP_OBJECTTYPE_EVT: /* "EventObj" */ 844 return (ACPI_BTYPE_EVENT); 845 846 case PARSEOP_OBJECTTYPE_FLD: /* "FieldUnitObj" */ 847 return (ACPI_BTYPE_FIELD_UNIT); 848 849 case PARSEOP_OBJECTTYPE_INT: /* "IntObj" */ 850 return (ACPI_BTYPE_INTEGER); 851 852 case PARSEOP_OBJECTTYPE_MTH: /* "MethodObj" */ 853 return (ACPI_BTYPE_METHOD); 854 855 case PARSEOP_OBJECTTYPE_MTX: /* "MutexObj" */ 856 return (ACPI_BTYPE_MUTEX); 857 858 case PARSEOP_OBJECTTYPE_OPR: /* "OpRegionObj" */ 859 return (ACPI_BTYPE_REGION); 860 861 case PARSEOP_OBJECTTYPE_PKG: /* "PkgObj" */ 862 return (ACPI_BTYPE_PACKAGE); 863 864 case PARSEOP_OBJECTTYPE_POW: /* "PowerResObj" */ 865 return (ACPI_BTYPE_POWER); 866 867 case PARSEOP_OBJECTTYPE_STR: /* "StrObj" */ 868 return (ACPI_BTYPE_STRING); 869 870 case PARSEOP_OBJECTTYPE_THZ: /* "ThermalZoneObj" */ 871 return (ACPI_BTYPE_THERMAL); 872 873 case PARSEOP_OBJECTTYPE_UNK: /* "UnknownObj" */ 874 return (ACPI_BTYPE_OBJECTS_AND_REFS); 875 876 default: 877 return (0); 878 } 879 } 880 881 882 /******************************************************************************* 883 * 884 * FUNCTION: AnMethodAnalysisWalkBegin 885 * 886 * PARAMETERS: ASL_WALK_CALLBACK 887 * 888 * RETURN: Status 889 * 890 * DESCRIPTION: Descending callback for the analysis walk. Check methods for: 891 * 1) Initialized local variables 892 * 2) Valid arguments 893 * 3) Return types 894 * 895 ******************************************************************************/ 896 897 ACPI_STATUS 898 AnMethodAnalysisWalkBegin ( 899 ACPI_PARSE_OBJECT *Op, 900 UINT32 Level, 901 void *Context) 902 { 903 ASL_ANALYSIS_WALK_INFO *WalkInfo = (ASL_ANALYSIS_WALK_INFO *) Context; 904 ASL_METHOD_INFO *MethodInfo = WalkInfo->MethodStack; 905 ACPI_PARSE_OBJECT *Next; 906 UINT32 RegisterNumber; 907 UINT32 i; 908 char LocalName[] = "Local0"; 909 char ArgName[] = "Arg0"; 910 ACPI_PARSE_OBJECT *ArgNode; 911 ACPI_PARSE_OBJECT *NextType; 912 ACPI_PARSE_OBJECT *NextParamType; 913 UINT8 ActualArgs = 0; 914 915 916 switch (Op->Asl.ParseOpcode) 917 { 918 case PARSEOP_METHOD: 919 920 TotalMethods++; 921 922 /* Create and init method info */ 923 924 MethodInfo = UtLocalCalloc (sizeof (ASL_METHOD_INFO)); 925 MethodInfo->Next = WalkInfo->MethodStack; 926 MethodInfo->Op = Op; 927 928 WalkInfo->MethodStack = MethodInfo; 929 930 /* Get the name node, ignored here */ 931 932 Next = Op->Asl.Child; 933 934 /* Get the NumArguments node */ 935 936 Next = Next->Asl.Next; 937 MethodInfo->NumArguments = (UINT8) 938 (((UINT8) Next->Asl.Value.Integer) & 0x07); 939 940 /* Get the SerializeRule and SyncLevel nodes, ignored here */ 941 942 Next = Next->Asl.Next; 943 Next = Next->Asl.Next; 944 ArgNode = Next; 945 946 /* Get the ReturnType node */ 947 948 Next = Next->Asl.Next; 949 950 NextType = Next->Asl.Child; 951 while (NextType) 952 { 953 /* Get and map each of the ReturnTypes */ 954 955 MethodInfo->ValidReturnTypes |= AnMapObjTypeToBtype (NextType); 956 NextType->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG; 957 NextType = NextType->Asl.Next; 958 } 959 960 /* Get the ParameterType node */ 961 962 Next = Next->Asl.Next; 963 964 NextType = Next->Asl.Child; 965 while (NextType) 966 { 967 if (NextType->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG) 968 { 969 NextParamType = NextType->Asl.Child; 970 while (NextParamType) 971 { 972 MethodInfo->ValidArgTypes[ActualArgs] |= AnMapObjTypeToBtype (NextParamType); 973 NextParamType->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG; 974 NextParamType = NextParamType->Asl.Next; 975 } 976 } 977 else 978 { 979 MethodInfo->ValidArgTypes[ActualArgs] = 980 AnMapObjTypeToBtype (NextType); 981 NextType->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG; 982 ActualArgs++; 983 } 984 985 NextType = NextType->Asl.Next; 986 } 987 988 if ((MethodInfo->NumArguments) && 989 (MethodInfo->NumArguments != ActualArgs)) 990 { 991 /* error: Param list did not match number of args */ 992 } 993 994 /* Allow numarguments == 0 for Function() */ 995 996 if ((!MethodInfo->NumArguments) && (ActualArgs)) 997 { 998 MethodInfo->NumArguments = ActualArgs; 999 ArgNode->Asl.Value.Integer |= ActualArgs; 1000 } 1001 1002 /* 1003 * Actual arguments are initialized at method entry. 1004 * All other ArgX "registers" can be used as locals, so we 1005 * track their initialization. 1006 */ 1007 for (i = 0; i < MethodInfo->NumArguments; i++) 1008 { 1009 MethodInfo->ArgInitialized[i] = TRUE; 1010 } 1011 break; 1012 1013 1014 case PARSEOP_METHODCALL: 1015 1016 if (MethodInfo && 1017 (Op->Asl.Node == MethodInfo->Op->Asl.Node)) 1018 { 1019 AslError (ASL_REMARK, ASL_MSG_RECURSION, Op, Op->Asl.ExternalName); 1020 } 1021 break; 1022 1023 1024 case PARSEOP_LOCAL0: 1025 case PARSEOP_LOCAL1: 1026 case PARSEOP_LOCAL2: 1027 case PARSEOP_LOCAL3: 1028 case PARSEOP_LOCAL4: 1029 case PARSEOP_LOCAL5: 1030 case PARSEOP_LOCAL6: 1031 case PARSEOP_LOCAL7: 1032 1033 if (!MethodInfo) 1034 { 1035 /* 1036 * Local was used outside a control method, or there was an error 1037 * in the method declaration. 1038 */ 1039 AslError (ASL_REMARK, ASL_MSG_LOCAL_OUTSIDE_METHOD, Op, Op->Asl.ExternalName); 1040 return (AE_ERROR); 1041 } 1042 1043 RegisterNumber = (Op->Asl.AmlOpcode & 0x000F); 1044 1045 /* 1046 * If the local is being used as a target, mark the local 1047 * initialized 1048 */ 1049 if (Op->Asl.CompileFlags & NODE_IS_TARGET) 1050 { 1051 MethodInfo->LocalInitialized[RegisterNumber] = TRUE; 1052 } 1053 1054 /* 1055 * Otherwise, this is a reference, check if the local 1056 * has been previously initialized. 1057 * 1058 * The only operator that accepts an uninitialized value is ObjectType() 1059 */ 1060 else if ((!MethodInfo->LocalInitialized[RegisterNumber]) && 1061 (Op->Asl.Parent->Asl.ParseOpcode != PARSEOP_OBJECTTYPE)) 1062 { 1063 LocalName[strlen (LocalName) -1] = (char) (RegisterNumber + 0x30); 1064 AslError (ASL_ERROR, ASL_MSG_LOCAL_INIT, Op, LocalName); 1065 } 1066 break; 1067 1068 1069 case PARSEOP_ARG0: 1070 case PARSEOP_ARG1: 1071 case PARSEOP_ARG2: 1072 case PARSEOP_ARG3: 1073 case PARSEOP_ARG4: 1074 case PARSEOP_ARG5: 1075 case PARSEOP_ARG6: 1076 1077 if (!MethodInfo) 1078 { 1079 /* 1080 * Arg was used outside a control method, or there was an error 1081 * in the method declaration. 1082 */ 1083 AslError (ASL_REMARK, ASL_MSG_LOCAL_OUTSIDE_METHOD, Op, Op->Asl.ExternalName); 1084 return (AE_ERROR); 1085 } 1086 1087 RegisterNumber = (Op->Asl.AmlOpcode & 0x000F) - 8; 1088 ArgName[strlen (ArgName) -1] = (char) (RegisterNumber + 0x30); 1089 1090 /* 1091 * If the Arg is being used as a target, mark the local 1092 * initialized 1093 */ 1094 if (Op->Asl.CompileFlags & NODE_IS_TARGET) 1095 { 1096 MethodInfo->ArgInitialized[RegisterNumber] = TRUE; 1097 } 1098 1099 /* 1100 * Otherwise, this is a reference, check if the Arg 1101 * has been previously initialized. 1102 * 1103 * The only operator that accepts an uninitialized value is ObjectType() 1104 */ 1105 else if ((!MethodInfo->ArgInitialized[RegisterNumber]) && 1106 (Op->Asl.Parent->Asl.ParseOpcode != PARSEOP_OBJECTTYPE)) 1107 { 1108 AslError (ASL_ERROR, ASL_MSG_ARG_INIT, Op, ArgName); 1109 } 1110 1111 /* Flag this arg if it is not a "real" argument to the method */ 1112 1113 if (RegisterNumber >= MethodInfo->NumArguments) 1114 { 1115 AslError (ASL_REMARK, ASL_MSG_NOT_PARAMETER, Op, ArgName); 1116 } 1117 break; 1118 1119 1120 case PARSEOP_RETURN: 1121 1122 if (!MethodInfo) 1123 { 1124 /* 1125 * Probably was an error in the method declaration, 1126 * no additional error here 1127 */ 1128 ACPI_WARNING ((AE_INFO, "%p, No parent method", Op)); 1129 return (AE_ERROR); 1130 } 1131 1132 /* Child indicates a return value */ 1133 1134 if ((Op->Asl.Child) && 1135 (Op->Asl.Child->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG)) 1136 { 1137 MethodInfo->NumReturnWithValue++; 1138 } 1139 else 1140 { 1141 MethodInfo->NumReturnNoValue++; 1142 } 1143 break; 1144 1145 1146 case PARSEOP_BREAK: 1147 case PARSEOP_CONTINUE: 1148 1149 Next = Op->Asl.Parent; 1150 while (Next) 1151 { 1152 if (Next->Asl.ParseOpcode == PARSEOP_WHILE) 1153 { 1154 break; 1155 } 1156 Next = Next->Asl.Parent; 1157 } 1158 1159 if (!Next) 1160 { 1161 AslError (ASL_ERROR, ASL_MSG_NO_WHILE, Op, NULL); 1162 } 1163 break; 1164 1165 1166 case PARSEOP_STALL: 1167 1168 /* We can range check if the argument is an integer */ 1169 1170 if ((Op->Asl.Child->Asl.ParseOpcode == PARSEOP_INTEGER) && 1171 (Op->Asl.Child->Asl.Value.Integer > ACPI_UINT8_MAX)) 1172 { 1173 AslError (ASL_ERROR, ASL_MSG_INVALID_TIME, Op, NULL); 1174 } 1175 break; 1176 1177 1178 case PARSEOP_DEVICE: 1179 case PARSEOP_EVENT: 1180 case PARSEOP_MUTEX: 1181 case PARSEOP_OPERATIONREGION: 1182 case PARSEOP_POWERRESOURCE: 1183 case PARSEOP_PROCESSOR: 1184 case PARSEOP_THERMALZONE: 1185 1186 /* 1187 * The first operand is a name to be created in the namespace. 1188 * Check against the reserved list. 1189 */ 1190 i = AnCheckForReservedName (Op, Op->Asl.NameSeg); 1191 if (i < ACPI_VALID_RESERVED_NAME_MAX) 1192 { 1193 AslError (ASL_ERROR, ASL_MSG_RESERVED_USE, Op, Op->Asl.ExternalName); 1194 } 1195 break; 1196 1197 1198 case PARSEOP_NAME: 1199 1200 i = AnCheckForReservedName (Op, Op->Asl.NameSeg); 1201 if (i < ACPI_VALID_RESERVED_NAME_MAX) 1202 { 1203 if (ReservedMethods[i].NumArguments > 0) 1204 { 1205 /* 1206 * This reserved name must be a control method because 1207 * it must have arguments 1208 */ 1209 AslError (ASL_ERROR, ASL_MSG_RESERVED_METHOD, Op, 1210 "with arguments"); 1211 } 1212 1213 /* Typechecking for _HID */ 1214 1215 else if (!ACPI_STRCMP (METHOD_NAME__HID, ReservedMethods[i].Name)) 1216 { 1217 /* Examine the second operand to typecheck it */ 1218 1219 Next = Op->Asl.Child->Asl.Next; 1220 1221 if ((Next->Asl.ParseOpcode != PARSEOP_INTEGER) && 1222 (Next->Asl.ParseOpcode != PARSEOP_STRING_LITERAL)) 1223 { 1224 /* _HID must be a string or an integer */ 1225 1226 AslError (ASL_ERROR, ASL_MSG_RESERVED_OPERAND_TYPE, Next, 1227 "String or Integer"); 1228 } 1229 1230 if (Next->Asl.ParseOpcode == PARSEOP_STRING_LITERAL) 1231 { 1232 /* 1233 * _HID is a string, all characters must be alphanumeric. 1234 * One of the things we want to catch here is the use of 1235 * a leading asterisk in the string. 1236 */ 1237 for (i = 0; Next->Asl.Value.String[i]; i++) 1238 { 1239 if (!isalnum (Next->Asl.Value.String[i])) 1240 { 1241 AslError (ASL_ERROR, ASL_MSG_ALPHANUMERIC_STRING, 1242 Next, Next->Asl.Value.String); 1243 break; 1244 } 1245 } 1246 } 1247 } 1248 } 1249 break; 1250 1251 1252 default: 1253 break; 1254 } 1255 1256 return AE_OK; 1257 } 1258 1259 1260 /******************************************************************************* 1261 * 1262 * FUNCTION: AnLastStatementIsReturn 1263 * 1264 * PARAMETERS: Op - A method parse node 1265 * 1266 * RETURN: TRUE if last statement is an ASL RETURN. False otherwise 1267 * 1268 * DESCRIPTION: Walk down the list of top level statements within a method 1269 * to find the last one. Check if that last statement is in 1270 * fact a RETURN statement. 1271 * 1272 ******************************************************************************/ 1273 1274 static BOOLEAN 1275 AnLastStatementIsReturn ( 1276 ACPI_PARSE_OBJECT *Op) 1277 { 1278 ACPI_PARSE_OBJECT *Next; 1279 1280 1281 /* 1282 * Check if last statement is a return 1283 */ 1284 Next = ASL_GET_CHILD_NODE (Op); 1285 while (Next) 1286 { 1287 if ((!Next->Asl.Next) && 1288 (Next->Asl.ParseOpcode == PARSEOP_RETURN)) 1289 { 1290 return TRUE; 1291 } 1292 1293 Next = ASL_GET_PEER_NODE (Next); 1294 } 1295 1296 return FALSE; 1297 } 1298 1299 1300 /******************************************************************************* 1301 * 1302 * FUNCTION: AnMethodAnalysisWalkEnd 1303 * 1304 * PARAMETERS: ASL_WALK_CALLBACK 1305 * 1306 * RETURN: Status 1307 * 1308 * DESCRIPTION: Ascending callback for analysis walk. Complete method 1309 * return analysis. 1310 * 1311 ******************************************************************************/ 1312 1313 ACPI_STATUS 1314 AnMethodAnalysisWalkEnd ( 1315 ACPI_PARSE_OBJECT *Op, 1316 UINT32 Level, 1317 void *Context) 1318 { 1319 ASL_ANALYSIS_WALK_INFO *WalkInfo = (ASL_ANALYSIS_WALK_INFO *) Context; 1320 ASL_METHOD_INFO *MethodInfo = WalkInfo->MethodStack; 1321 1322 1323 switch (Op->Asl.ParseOpcode) 1324 { 1325 case PARSEOP_METHOD: 1326 case PARSEOP_RETURN: 1327 if (!MethodInfo) 1328 { 1329 printf ("No method info for method! [%s]\n", Op->Asl.Namepath); 1330 AslError (ASL_ERROR, ASL_MSG_COMPILER_INTERNAL, Op, 1331 "No method info for this method"); 1332 CmCleanupAndExit (); 1333 return (AE_AML_INTERNAL); 1334 } 1335 break; 1336 1337 default: 1338 break; 1339 } 1340 1341 switch (Op->Asl.ParseOpcode) 1342 { 1343 case PARSEOP_METHOD: 1344 1345 WalkInfo->MethodStack = MethodInfo->Next; 1346 1347 /* 1348 * Check if there is no return statement at the end of the 1349 * method AND we can actually get there -- i.e., the execution 1350 * of the method can possibly terminate without a return statement. 1351 */ 1352 if ((!AnLastStatementIsReturn (Op)) && 1353 (!(Op->Asl.CompileFlags & NODE_HAS_NO_EXIT))) 1354 { 1355 /* 1356 * No return statement, and execution can possibly exit 1357 * via this path. This is equivalent to Return () 1358 */ 1359 MethodInfo->NumReturnNoValue++; 1360 } 1361 1362 /* 1363 * Check for case where some return statements have a return value 1364 * and some do not. Exit without a return statement is a return with 1365 * no value 1366 */ 1367 if (MethodInfo->NumReturnNoValue && 1368 MethodInfo->NumReturnWithValue) 1369 { 1370 AslError (ASL_WARNING, ASL_MSG_RETURN_TYPES, Op, 1371 Op->Asl.ExternalName); 1372 } 1373 1374 /* 1375 * If there are any RETURN() statements with no value, or there is a 1376 * control path that allows the method to exit without a return value, 1377 * we mark the method as a method that does not return a value. This 1378 * knowledge can be used to check method invocations that expect a 1379 * returned value. 1380 */ 1381 if (MethodInfo->NumReturnNoValue) 1382 { 1383 if (MethodInfo->NumReturnWithValue) 1384 { 1385 Op->Asl.CompileFlags |= NODE_METHOD_SOME_NO_RETVAL; 1386 } 1387 else 1388 { 1389 Op->Asl.CompileFlags |= NODE_METHOD_NO_RETVAL; 1390 } 1391 } 1392 1393 /* 1394 * Check predefined method names for correct return behavior 1395 * and correct number of arguments 1396 */ 1397 AnCheckForReservedMethod (Op, MethodInfo); 1398 ACPI_FREE (MethodInfo); 1399 break; 1400 1401 1402 case PARSEOP_RETURN: 1403 1404 /* 1405 * The parent block does not "exit" and continue execution -- the 1406 * method is terminated here with the Return() statement. 1407 */ 1408 Op->Asl.Parent->Asl.CompileFlags |= NODE_HAS_NO_EXIT; 1409 1410 /* Used in the "typing" pass later */ 1411 1412 Op->Asl.ParentMethod = MethodInfo->Op; 1413 1414 /* 1415 * If there is a peer node after the return statement, then this 1416 * node is unreachable code -- i.e., it won't be executed because of 1417 * the preceeding Return() statement. 1418 */ 1419 if (Op->Asl.Next) 1420 { 1421 AslError (ASL_WARNING, ASL_MSG_UNREACHABLE_CODE, Op->Asl.Next, NULL); 1422 } 1423 break; 1424 1425 1426 case PARSEOP_IF: 1427 1428 if ((Op->Asl.CompileFlags & NODE_HAS_NO_EXIT) && 1429 (Op->Asl.Next) && 1430 (Op->Asl.Next->Asl.ParseOpcode == PARSEOP_ELSE)) 1431 { 1432 /* 1433 * This IF has a corresponding ELSE. The IF block has no exit, 1434 * (it contains an unconditional Return) 1435 * mark the ELSE block to remember this fact. 1436 */ 1437 Op->Asl.Next->Asl.CompileFlags |= NODE_IF_HAS_NO_EXIT; 1438 } 1439 break; 1440 1441 1442 case PARSEOP_ELSE: 1443 1444 if ((Op->Asl.CompileFlags & NODE_HAS_NO_EXIT) && 1445 (Op->Asl.CompileFlags & NODE_IF_HAS_NO_EXIT)) 1446 { 1447 /* 1448 * This ELSE block has no exit and the corresponding IF block 1449 * has no exit either. Therefore, the parent node has no exit. 1450 */ 1451 Op->Asl.Parent->Asl.CompileFlags |= NODE_HAS_NO_EXIT; 1452 } 1453 break; 1454 1455 1456 default: 1457 1458 if ((Op->Asl.CompileFlags & NODE_HAS_NO_EXIT) && 1459 (Op->Asl.Parent)) 1460 { 1461 /* If this node has no exit, then the parent has no exit either */ 1462 1463 Op->Asl.Parent->Asl.CompileFlags |= NODE_HAS_NO_EXIT; 1464 } 1465 break; 1466 } 1467 1468 return AE_OK; 1469 } 1470 1471 1472 /******************************************************************************* 1473 * 1474 * FUNCTION: AnMethodTypingWalkBegin 1475 * 1476 * PARAMETERS: ASL_WALK_CALLBACK 1477 * 1478 * RETURN: Status 1479 * 1480 * DESCRIPTION: Descending callback for the typing walk. 1481 * 1482 ******************************************************************************/ 1483 1484 ACPI_STATUS 1485 AnMethodTypingWalkBegin ( 1486 ACPI_PARSE_OBJECT *Op, 1487 UINT32 Level, 1488 void *Context) 1489 { 1490 1491 return AE_OK; 1492 } 1493 1494 1495 /******************************************************************************* 1496 * 1497 * FUNCTION: AnMethodTypingWalkEnd 1498 * 1499 * PARAMETERS: ASL_WALK_CALLBACK 1500 * 1501 * RETURN: Status 1502 * 1503 * DESCRIPTION: Ascending callback for typing walk. Complete the method 1504 * return analysis. Check methods for: 1505 * 1) Initialized local variables 1506 * 2) Valid arguments 1507 * 3) Return types 1508 * 1509 ******************************************************************************/ 1510 1511 ACPI_STATUS 1512 AnMethodTypingWalkEnd ( 1513 ACPI_PARSE_OBJECT *Op, 1514 UINT32 Level, 1515 void *Context) 1516 { 1517 UINT32 ThisNodeBtype; 1518 1519 1520 switch (Op->Asl.ParseOpcode) 1521 { 1522 case PARSEOP_METHOD: 1523 1524 Op->Asl.CompileFlags |= NODE_METHOD_TYPED; 1525 break; 1526 1527 case PARSEOP_RETURN: 1528 1529 if ((Op->Asl.Child) && 1530 (Op->Asl.Child->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG)) 1531 { 1532 ThisNodeBtype = AnGetBtype (Op->Asl.Child); 1533 1534 if ((Op->Asl.Child->Asl.ParseOpcode == PARSEOP_METHODCALL) && 1535 (ThisNodeBtype == (ACPI_UINT32_MAX -1))) 1536 { 1537 /* 1538 * The called method is untyped at this time (typically a 1539 * forward reference). 1540 * 1541 * Check for a recursive method call first. 1542 */ 1543 if (Op->Asl.ParentMethod != Op->Asl.Child->Asl.Node->Op) 1544 { 1545 /* We must type the method here */ 1546 1547 TrWalkParseTree (Op->Asl.Child->Asl.Node->Op, 1548 ASL_WALK_VISIT_TWICE, AnMethodTypingWalkBegin, 1549 AnMethodTypingWalkEnd, NULL); 1550 1551 ThisNodeBtype = AnGetBtype (Op->Asl.Child); 1552 } 1553 } 1554 1555 /* Returns a value, save the value type */ 1556 1557 if (Op->Asl.ParentMethod) 1558 { 1559 Op->Asl.ParentMethod->Asl.AcpiBtype |= ThisNodeBtype; 1560 } 1561 } 1562 break; 1563 1564 default: 1565 break; 1566 } 1567 1568 return AE_OK; 1569 } 1570 1571 1572 /******************************************************************************* 1573 * 1574 * FUNCTION: AnCheckMethodReturnValue 1575 * 1576 * PARAMETERS: Op - Parent 1577 * OpInfo - Parent info 1578 * ArgOp - Method invocation op 1579 * RequiredBtypes - What caller requires 1580 * ThisNodeBtype - What this node returns (if anything) 1581 * 1582 * RETURN: None 1583 * 1584 * DESCRIPTION: Check a method invocation for 1) A return value and if it does 1585 * in fact return a value, 2) check the type of the return value. 1586 * 1587 ******************************************************************************/ 1588 1589 static void 1590 AnCheckMethodReturnValue ( 1591 ACPI_PARSE_OBJECT *Op, 1592 const ACPI_OPCODE_INFO *OpInfo, 1593 ACPI_PARSE_OBJECT *ArgOp, 1594 UINT32 RequiredBtypes, 1595 UINT32 ThisNodeBtype) 1596 { 1597 ACPI_PARSE_OBJECT *OwningOp; 1598 ACPI_NAMESPACE_NODE *Node; 1599 1600 1601 Node = ArgOp->Asl.Node; 1602 1603 1604 /* Examine the parent op of this method */ 1605 1606 OwningOp = Node->Op; 1607 if (OwningOp->Asl.CompileFlags & NODE_METHOD_NO_RETVAL) 1608 { 1609 /* Method NEVER returns a value */ 1610 1611 AslError (ASL_ERROR, ASL_MSG_NO_RETVAL, Op, Op->Asl.ExternalName); 1612 } 1613 else if (OwningOp->Asl.CompileFlags & NODE_METHOD_SOME_NO_RETVAL) 1614 { 1615 /* Method SOMETIMES returns a value, SOMETIMES not */ 1616 1617 AslError (ASL_WARNING, ASL_MSG_SOME_NO_RETVAL, Op, Op->Asl.ExternalName); 1618 } 1619 else if (!(ThisNodeBtype & RequiredBtypes)) 1620 { 1621 /* Method returns a value, but the type is wrong */ 1622 1623 AnFormatBtype (StringBuffer, ThisNodeBtype); 1624 AnFormatBtype (StringBuffer2, RequiredBtypes); 1625 1626 1627 /* 1628 * The case where the method does not return any value at all 1629 * was already handled in the namespace cross reference 1630 * -- Only issue an error if the method in fact returns a value, 1631 * but it is of the wrong type 1632 */ 1633 if (ThisNodeBtype != 0) 1634 { 1635 sprintf (MsgBuffer, 1636 "Method returns [%s], %s operator requires [%s]", 1637 StringBuffer, OpInfo->Name, StringBuffer2); 1638 1639 AslError (ASL_ERROR, ASL_MSG_INVALID_TYPE, ArgOp, MsgBuffer); 1640 } 1641 } 1642 } 1643 1644 1645 /******************************************************************************* 1646 * 1647 * FUNCTION: AnOperandTypecheckWalkBegin 1648 * 1649 * PARAMETERS: ASL_WALK_CALLBACK 1650 * 1651 * RETURN: Status 1652 * 1653 * DESCRIPTION: Descending callback for the analysis walk. Check methods for: 1654 * 1) Initialized local variables 1655 * 2) Valid arguments 1656 * 3) Return types 1657 * 1658 ******************************************************************************/ 1659 1660 ACPI_STATUS 1661 AnOperandTypecheckWalkBegin ( 1662 ACPI_PARSE_OBJECT *Op, 1663 UINT32 Level, 1664 void *Context) 1665 { 1666 1667 return AE_OK; 1668 } 1669 1670 1671 /******************************************************************************* 1672 * 1673 * FUNCTION: AnOperandTypecheckWalkEnd 1674 * 1675 * PARAMETERS: ASL_WALK_CALLBACK 1676 * 1677 * RETURN: Status 1678 * 1679 * DESCRIPTION: Ascending callback for analysis walk. Complete method 1680 * return analysis. 1681 * 1682 ******************************************************************************/ 1683 1684 ACPI_STATUS 1685 AnOperandTypecheckWalkEnd ( 1686 ACPI_PARSE_OBJECT *Op, 1687 UINT32 Level, 1688 void *Context) 1689 { 1690 const ACPI_OPCODE_INFO *OpInfo; 1691 UINT32 RuntimeArgTypes; 1692 UINT32 RuntimeArgTypes2; 1693 UINT32 RequiredBtypes; 1694 UINT32 ThisNodeBtype; 1695 UINT32 CommonBtypes; 1696 UINT32 OpcodeClass; 1697 ACPI_PARSE_OBJECT *ArgOp; 1698 UINT32 ArgType; 1699 1700 1701 switch (Op->Asl.AmlOpcode) 1702 { 1703 case AML_RAW_DATA_BYTE: 1704 case AML_RAW_DATA_WORD: 1705 case AML_RAW_DATA_DWORD: 1706 case AML_RAW_DATA_QWORD: 1707 case AML_RAW_DATA_BUFFER: 1708 case AML_RAW_DATA_CHAIN: 1709 case AML_PACKAGE_LENGTH: 1710 case AML_UNASSIGNED_OPCODE: 1711 case AML_DEFAULT_ARG_OP: 1712 1713 /* Ignore the internal (compiler-only) AML opcodes */ 1714 1715 return (AE_OK); 1716 1717 default: 1718 break; 1719 } 1720 1721 OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode); 1722 if (!OpInfo) 1723 { 1724 return (AE_OK); 1725 } 1726 1727 ArgOp = Op->Asl.Child; 1728 RuntimeArgTypes = OpInfo->RuntimeArgs; 1729 OpcodeClass = OpInfo->Class; 1730 1731 #ifdef ASL_ERROR_NAMED_OBJECT_IN_WHILE 1732 /* 1733 * Update 11/2008: In practice, we can't perform this check. A simple 1734 * analysis is not sufficient. Also, it can cause errors when compiling 1735 * disassembled code because of the way Switch operators are implemented 1736 * (a While(One) loop with a named temp variable created within.) 1737 */ 1738 1739 /* 1740 * If we are creating a named object, check if we are within a while loop 1741 * by checking if the parent is a WHILE op. This is a simple analysis, but 1742 * probably sufficient for many cases. 1743 * 1744 * Allow Scope(), Buffer(), and Package(). 1745 */ 1746 if (((OpcodeClass == AML_CLASS_NAMED_OBJECT) && (Op->Asl.AmlOpcode != AML_SCOPE_OP)) || 1747 ((OpcodeClass == AML_CLASS_CREATE) && (OpInfo->Flags & AML_NSNODE))) 1748 { 1749 if (Op->Asl.Parent->Asl.AmlOpcode == AML_WHILE_OP) 1750 { 1751 AslError (ASL_ERROR, ASL_MSG_NAMED_OBJECT_IN_WHILE, Op, NULL); 1752 } 1753 } 1754 #endif 1755 1756 /* 1757 * Special case for control opcodes IF/RETURN/WHILE since they 1758 * have no runtime arg list (at this time) 1759 */ 1760 switch (Op->Asl.AmlOpcode) 1761 { 1762 case AML_IF_OP: 1763 case AML_WHILE_OP: 1764 case AML_RETURN_OP: 1765 1766 if (ArgOp->Asl.ParseOpcode == PARSEOP_METHODCALL) 1767 { 1768 /* Check for an internal method */ 1769 1770 if (AnIsInternalMethod (ArgOp)) 1771 { 1772 return (AE_OK); 1773 } 1774 1775 /* The lone arg is a method call, check it */ 1776 1777 RequiredBtypes = AnMapArgTypeToBtype (ARGI_INTEGER); 1778 if (Op->Asl.AmlOpcode == AML_RETURN_OP) 1779 { 1780 RequiredBtypes = 0xFFFFFFFF; 1781 } 1782 1783 ThisNodeBtype = AnGetBtype (ArgOp); 1784 if (ThisNodeBtype == ACPI_UINT32_MAX) 1785 { 1786 return (AE_OK); 1787 } 1788 AnCheckMethodReturnValue (Op, OpInfo, ArgOp, 1789 RequiredBtypes, ThisNodeBtype); 1790 } 1791 return (AE_OK); 1792 1793 default: 1794 break; 1795 } 1796 1797 /* Ignore the non-executable opcodes */ 1798 1799 if (RuntimeArgTypes == ARGI_INVALID_OPCODE) 1800 { 1801 return (AE_OK); 1802 } 1803 1804 switch (OpcodeClass) 1805 { 1806 case AML_CLASS_EXECUTE: 1807 case AML_CLASS_CREATE: 1808 case AML_CLASS_CONTROL: 1809 case AML_CLASS_RETURN_VALUE: 1810 1811 /* TBD: Change class or fix typechecking for these */ 1812 1813 if ((Op->Asl.AmlOpcode == AML_BUFFER_OP) || 1814 (Op->Asl.AmlOpcode == AML_PACKAGE_OP) || 1815 (Op->Asl.AmlOpcode == AML_VAR_PACKAGE_OP)) 1816 { 1817 break; 1818 } 1819 1820 /* Reverse the runtime argument list */ 1821 1822 RuntimeArgTypes2 = 0; 1823 while ((ArgType = GET_CURRENT_ARG_TYPE (RuntimeArgTypes))) 1824 { 1825 RuntimeArgTypes2 <<= ARG_TYPE_WIDTH; 1826 RuntimeArgTypes2 |= ArgType; 1827 INCREMENT_ARG_LIST (RuntimeArgTypes); 1828 } 1829 1830 while ((ArgType = GET_CURRENT_ARG_TYPE (RuntimeArgTypes2))) 1831 { 1832 RequiredBtypes = AnMapArgTypeToBtype (ArgType); 1833 1834 ThisNodeBtype = AnGetBtype (ArgOp); 1835 if (ThisNodeBtype == ACPI_UINT32_MAX) 1836 { 1837 goto NextArgument; 1838 } 1839 1840 /* Examine the arg based on the required type of the arg */ 1841 1842 switch (ArgType) 1843 { 1844 case ARGI_TARGETREF: 1845 1846 if (ArgOp->Asl.ParseOpcode == PARSEOP_ZERO) 1847 { 1848 /* ZERO is the placeholder for "don't store result" */ 1849 1850 ThisNodeBtype = RequiredBtypes; 1851 break; 1852 } 1853 1854 if (ArgOp->Asl.ParseOpcode == PARSEOP_INTEGER) 1855 { 1856 /* 1857 * This is the case where an original reference to a resource 1858 * descriptor field has been replaced by an (Integer) offset. 1859 * These named fields are supported at compile-time only; 1860 * the names are not passed to the interpreter (via the AML). 1861 */ 1862 if ((ArgOp->Asl.Node->Type == ACPI_TYPE_LOCAL_RESOURCE_FIELD) || 1863 (ArgOp->Asl.Node->Type == ACPI_TYPE_LOCAL_RESOURCE)) 1864 { 1865 AslError (ASL_ERROR, ASL_MSG_RESOURCE_FIELD, ArgOp, NULL); 1866 } 1867 else 1868 { 1869 AslError (ASL_ERROR, ASL_MSG_INVALID_TYPE, ArgOp, NULL); 1870 } 1871 break; 1872 } 1873 1874 if ((ArgOp->Asl.ParseOpcode == PARSEOP_METHODCALL) || 1875 (ArgOp->Asl.ParseOpcode == PARSEOP_DEREFOF)) 1876 { 1877 break; 1878 } 1879 1880 ThisNodeBtype = RequiredBtypes; 1881 break; 1882 1883 1884 case ARGI_REFERENCE: /* References */ 1885 case ARGI_INTEGER_REF: 1886 case ARGI_OBJECT_REF: 1887 case ARGI_DEVICE_REF: 1888 1889 switch (ArgOp->Asl.ParseOpcode) 1890 { 1891 case PARSEOP_LOCAL0: 1892 case PARSEOP_LOCAL1: 1893 case PARSEOP_LOCAL2: 1894 case PARSEOP_LOCAL3: 1895 case PARSEOP_LOCAL4: 1896 case PARSEOP_LOCAL5: 1897 case PARSEOP_LOCAL6: 1898 case PARSEOP_LOCAL7: 1899 1900 /* TBD: implement analysis of current value (type) of the local */ 1901 /* For now, just treat any local as a typematch */ 1902 1903 /*ThisNodeBtype = RequiredBtypes;*/ 1904 break; 1905 1906 case PARSEOP_ARG0: 1907 case PARSEOP_ARG1: 1908 case PARSEOP_ARG2: 1909 case PARSEOP_ARG3: 1910 case PARSEOP_ARG4: 1911 case PARSEOP_ARG5: 1912 case PARSEOP_ARG6: 1913 1914 /* Hard to analyze argument types, sow we won't */ 1915 /* For now, just treat any arg as a typematch */ 1916 1917 /* ThisNodeBtype = RequiredBtypes; */ 1918 break; 1919 1920 case PARSEOP_DEBUG: 1921 break; 1922 1923 case PARSEOP_REFOF: 1924 case PARSEOP_INDEX: 1925 default: 1926 break; 1927 1928 } 1929 break; 1930 1931 case ARGI_INTEGER: 1932 default: 1933 break; 1934 } 1935 1936 1937 CommonBtypes = ThisNodeBtype & RequiredBtypes; 1938 1939 if (ArgOp->Asl.ParseOpcode == PARSEOP_METHODCALL) 1940 { 1941 if (AnIsInternalMethod (ArgOp)) 1942 { 1943 return (AE_OK); 1944 } 1945 1946 /* Check a method call for a valid return value */ 1947 1948 AnCheckMethodReturnValue (Op, OpInfo, ArgOp, 1949 RequiredBtypes, ThisNodeBtype); 1950 } 1951 1952 /* 1953 * Now check if the actual type(s) match at least one 1954 * bit to the required type 1955 */ 1956 else if (!CommonBtypes) 1957 { 1958 /* No match -- this is a type mismatch error */ 1959 1960 AnFormatBtype (StringBuffer, ThisNodeBtype); 1961 AnFormatBtype (StringBuffer2, RequiredBtypes); 1962 1963 sprintf (MsgBuffer, "[%s] found, %s operator requires [%s]", 1964 StringBuffer, OpInfo->Name, StringBuffer2); 1965 1966 AslError (ASL_ERROR, ASL_MSG_INVALID_TYPE, ArgOp, MsgBuffer); 1967 } 1968 1969 NextArgument: 1970 ArgOp = ArgOp->Asl.Next; 1971 INCREMENT_ARG_LIST (RuntimeArgTypes2); 1972 } 1973 break; 1974 1975 default: 1976 break; 1977 } 1978 1979 return (AE_OK); 1980 } 1981 1982 1983 /******************************************************************************* 1984 * 1985 * FUNCTION: AnIsResultUsed 1986 * 1987 * PARAMETERS: Op - Parent op for the operator 1988 * 1989 * RETURN: TRUE if result from this operation is actually consumed 1990 * 1991 * DESCRIPTION: Determine if the function result value from an operator is 1992 * used. 1993 * 1994 ******************************************************************************/ 1995 1996 BOOLEAN 1997 AnIsResultUsed ( 1998 ACPI_PARSE_OBJECT *Op) 1999 { 2000 ACPI_PARSE_OBJECT *Parent; 2001 2002 2003 switch (Op->Asl.ParseOpcode) 2004 { 2005 case PARSEOP_INCREMENT: 2006 case PARSEOP_DECREMENT: 2007 2008 /* These are standalone operators, no return value */ 2009 2010 return (TRUE); 2011 2012 default: 2013 break; 2014 } 2015 2016 /* Examine parent to determine if the return value is used */ 2017 2018 Parent = Op->Asl.Parent; 2019 switch (Parent->Asl.ParseOpcode) 2020 { 2021 /* If/While - check if the operator is the predicate */ 2022 2023 case PARSEOP_IF: 2024 case PARSEOP_WHILE: 2025 2026 /* First child is the predicate */ 2027 2028 if (Parent->Asl.Child == Op) 2029 { 2030 return (TRUE); 2031 } 2032 return (FALSE); 2033 2034 /* Not used if one of these is the parent */ 2035 2036 case PARSEOP_METHOD: 2037 case PARSEOP_DEFINITIONBLOCK: 2038 case PARSEOP_ELSE: 2039 2040 return (FALSE); 2041 2042 default: 2043 /* Any other type of parent means that the result is used */ 2044 2045 return (TRUE); 2046 } 2047 } 2048 2049 2050 /******************************************************************************* 2051 * 2052 * FUNCTION: AnOtherSemanticAnalysisWalkBegin 2053 * 2054 * PARAMETERS: ASL_WALK_CALLBACK 2055 * 2056 * RETURN: Status 2057 * 2058 * DESCRIPTION: Descending callback for the analysis walk. Checks for 2059 * miscellaneous issues in the code. 2060 * 2061 ******************************************************************************/ 2062 2063 ACPI_STATUS 2064 AnOtherSemanticAnalysisWalkBegin ( 2065 ACPI_PARSE_OBJECT *Op, 2066 UINT32 Level, 2067 void *Context) 2068 { 2069 ACPI_PARSE_OBJECT *ArgNode; 2070 ACPI_PARSE_OBJECT *PrevArgNode = NULL; 2071 const ACPI_OPCODE_INFO *OpInfo; 2072 2073 2074 OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode); 2075 2076 /* 2077 * Determine if an execution class operator actually does something by 2078 * checking if it has a target and/or the function return value is used. 2079 * (Target is optional, so a standalone statement can actually do nothing.) 2080 */ 2081 if ((OpInfo->Class == AML_CLASS_EXECUTE) && 2082 (OpInfo->Flags & AML_HAS_RETVAL) && 2083 (!AnIsResultUsed (Op))) 2084 { 2085 if (OpInfo->Flags & AML_HAS_TARGET) 2086 { 2087 /* 2088 * Find the target node, it is always the last child. If the traget 2089 * is not specified in the ASL, a default node of type Zero was 2090 * created by the parser. 2091 */ 2092 ArgNode = Op->Asl.Child; 2093 while (ArgNode->Asl.Next) 2094 { 2095 PrevArgNode = ArgNode; 2096 ArgNode = ArgNode->Asl.Next; 2097 } 2098 2099 /* Divide() is the only weird case, it has two targets */ 2100 2101 if (Op->Asl.AmlOpcode == AML_DIVIDE_OP) 2102 { 2103 if ((ArgNode->Asl.ParseOpcode == PARSEOP_ZERO) && 2104 (PrevArgNode->Asl.ParseOpcode == PARSEOP_ZERO)) 2105 { 2106 AslError (ASL_WARNING, ASL_MSG_RESULT_NOT_USED, Op, Op->Asl.ExternalName); 2107 } 2108 } 2109 else if (ArgNode->Asl.ParseOpcode == PARSEOP_ZERO) 2110 { 2111 AslError (ASL_WARNING, ASL_MSG_RESULT_NOT_USED, Op, Op->Asl.ExternalName); 2112 } 2113 } 2114 else 2115 { 2116 /* 2117 * Has no target and the result is not used. Only a couple opcodes 2118 * can have this combination. 2119 */ 2120 switch (Op->Asl.ParseOpcode) 2121 { 2122 case PARSEOP_ACQUIRE: 2123 case PARSEOP_WAIT: 2124 case PARSEOP_LOADTABLE: 2125 break; 2126 2127 default: 2128 AslError (ASL_WARNING, ASL_MSG_RESULT_NOT_USED, Op, Op->Asl.ExternalName); 2129 break; 2130 } 2131 } 2132 } 2133 2134 2135 /* 2136 * Semantic checks for individual ASL operators 2137 */ 2138 switch (Op->Asl.ParseOpcode) 2139 { 2140 case PARSEOP_ACQUIRE: 2141 case PARSEOP_WAIT: 2142 /* 2143 * Emit a warning if the timeout parameter for these operators is not 2144 * ACPI_WAIT_FOREVER, and the result value from the operator is not 2145 * checked, meaning that a timeout could happen, but the code 2146 * would not know about it. 2147 */ 2148 2149 /* First child is the namepath, 2nd child is timeout */ 2150 2151 ArgNode = Op->Asl.Child; 2152 ArgNode = ArgNode->Asl.Next; 2153 2154 /* 2155 * Check for the WAIT_FOREVER case - defined by the ACPI spec to be 2156 * 0xFFFF or greater 2157 */ 2158 if (((ArgNode->Asl.ParseOpcode == PARSEOP_WORDCONST) || 2159 (ArgNode->Asl.ParseOpcode == PARSEOP_INTEGER)) && 2160 (ArgNode->Asl.Value.Integer >= (ACPI_INTEGER) ACPI_WAIT_FOREVER)) 2161 { 2162 break; 2163 } 2164 2165 /* 2166 * The operation could timeout. If the return value is not used 2167 * (indicates timeout occurred), issue a warning 2168 */ 2169 if (!AnIsResultUsed (Op)) 2170 { 2171 AslError (ASL_WARNING, ASL_MSG_TIMEOUT, ArgNode, Op->Asl.ExternalName); 2172 } 2173 break; 2174 2175 case PARSEOP_CREATEFIELD: 2176 /* 2177 * Check for a zero Length (NumBits) operand. NumBits is the 3rd operand 2178 */ 2179 ArgNode = Op->Asl.Child; 2180 ArgNode = ArgNode->Asl.Next; 2181 ArgNode = ArgNode->Asl.Next; 2182 2183 if ((ArgNode->Asl.ParseOpcode == PARSEOP_ZERO) || 2184 ((ArgNode->Asl.ParseOpcode == PARSEOP_INTEGER) && 2185 (ArgNode->Asl.Value.Integer == 0))) 2186 { 2187 AslError (ASL_ERROR, ASL_MSG_NON_ZERO, ArgNode, NULL); 2188 } 2189 break; 2190 2191 default: 2192 break; 2193 } 2194 2195 return AE_OK; 2196 } 2197 2198 2199 /******************************************************************************* 2200 * 2201 * FUNCTION: AnOtherSemanticAnalysisWalkEnd 2202 * 2203 * PARAMETERS: ASL_WALK_CALLBACK 2204 * 2205 * RETURN: Status 2206 * 2207 * DESCRIPTION: Ascending callback for analysis walk. Complete method 2208 * return analysis. 2209 * 2210 ******************************************************************************/ 2211 2212 ACPI_STATUS 2213 AnOtherSemanticAnalysisWalkEnd ( 2214 ACPI_PARSE_OBJECT *Op, 2215 UINT32 Level, 2216 void *Context) 2217 { 2218 2219 return AE_OK; 2220 2221 } 2222 2223 2224 #ifdef ACPI_OBSOLETE_FUNCTIONS 2225 /******************************************************************************* 2226 * 2227 * FUNCTION: AnMapBtypeToEtype 2228 * 2229 * PARAMETERS: Btype - Bitfield of ACPI types 2230 * 2231 * RETURN: The Etype corresponding the the Btype 2232 * 2233 * DESCRIPTION: Convert a bitfield type to an encoded type 2234 * 2235 ******************************************************************************/ 2236 2237 UINT32 2238 AnMapBtypeToEtype ( 2239 UINT32 Btype) 2240 { 2241 UINT32 i; 2242 UINT32 Etype; 2243 2244 2245 if (Btype == 0) 2246 { 2247 return 0; 2248 } 2249 2250 Etype = 1; 2251 for (i = 1; i < Btype; i *= 2) 2252 { 2253 Etype++; 2254 } 2255 2256 return (Etype); 2257 } 2258 #endif 2259 2260