aslanalyze.c revision 167802
1118611Snjl 2118611Snjl/****************************************************************************** 3118611Snjl * 4118611Snjl * Module Name: aslanalyze.c - check for semantic errors 5167802Sjkim * $Revision: 1.115 $ 6118611Snjl * 7118611Snjl *****************************************************************************/ 8118611Snjl 9118611Snjl/****************************************************************************** 10118611Snjl * 11118611Snjl * 1. Copyright Notice 12118611Snjl * 13167802Sjkim * Some or all of this work - Copyright (c) 1999 - 2007, Intel Corp. 14118611Snjl * All rights reserved. 15118611Snjl * 16118611Snjl * 2. License 17118611Snjl * 18118611Snjl * 2.1. This is your license from Intel Corp. under its intellectual property 19118611Snjl * rights. You may have additional license terms from the party that provided 20118611Snjl * you this software, covering your right to use that party's intellectual 21118611Snjl * property rights. 22118611Snjl * 23118611Snjl * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 24118611Snjl * copy of the source code appearing in this file ("Covered Code") an 25118611Snjl * irrevocable, perpetual, worldwide license under Intel's copyrights in the 26118611Snjl * base code distributed originally by Intel ("Original Intel Code") to copy, 27118611Snjl * make derivatives, distribute, use and display any portion of the Covered 28118611Snjl * Code in any form, with the right to sublicense such rights; and 29118611Snjl * 30118611Snjl * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 31118611Snjl * license (with the right to sublicense), under only those claims of Intel 32118611Snjl * patents that are infringed by the Original Intel Code, to make, use, sell, 33118611Snjl * offer to sell, and import the Covered Code and derivative works thereof 34118611Snjl * solely to the minimum extent necessary to exercise the above copyright 35118611Snjl * license, and in no event shall the patent license extend to any additions 36118611Snjl * to or modifications of the Original Intel Code. No other license or right 37118611Snjl * is granted directly or by implication, estoppel or otherwise; 38118611Snjl * 39118611Snjl * The above copyright and patent license is granted only if the following 40118611Snjl * conditions are met: 41118611Snjl * 42118611Snjl * 3. Conditions 43118611Snjl * 44118611Snjl * 3.1. Redistribution of Source with Rights to Further Distribute Source. 45118611Snjl * Redistribution of source code of any substantial portion of the Covered 46118611Snjl * Code or modification with rights to further distribute source must include 47118611Snjl * the above Copyright Notice, the above License, this list of Conditions, 48118611Snjl * and the following Disclaimer and Export Compliance provision. In addition, 49118611Snjl * Licensee must cause all Covered Code to which Licensee contributes to 50118611Snjl * contain a file documenting the changes Licensee made to create that Covered 51118611Snjl * Code and the date of any change. Licensee must include in that file the 52118611Snjl * documentation of any changes made by any predecessor Licensee. Licensee 53118611Snjl * must include a prominent statement that the modification is derived, 54118611Snjl * directly or indirectly, from Original Intel Code. 55118611Snjl * 56118611Snjl * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 57118611Snjl * Redistribution of source code of any substantial portion of the Covered 58118611Snjl * Code or modification without rights to further distribute source must 59118611Snjl * include the following Disclaimer and Export Compliance provision in the 60118611Snjl * documentation and/or other materials provided with distribution. In 61118611Snjl * addition, Licensee may not authorize further sublicense of source of any 62118611Snjl * portion of the Covered Code, and must include terms to the effect that the 63118611Snjl * license from Licensee to its licensee is limited to the intellectual 64118611Snjl * property embodied in the software Licensee provides to its licensee, and 65118611Snjl * not to intellectual property embodied in modifications its licensee may 66118611Snjl * make. 67118611Snjl * 68118611Snjl * 3.3. Redistribution of Executable. Redistribution in executable form of any 69118611Snjl * substantial portion of the Covered Code or modification must reproduce the 70118611Snjl * above Copyright Notice, and the following Disclaimer and Export Compliance 71118611Snjl * provision in the documentation and/or other materials provided with the 72118611Snjl * distribution. 73118611Snjl * 74118611Snjl * 3.4. Intel retains all right, title, and interest in and to the Original 75118611Snjl * Intel Code. 76118611Snjl * 77118611Snjl * 3.5. Neither the name Intel nor any other trademark owned or controlled by 78118611Snjl * Intel shall be used in advertising or otherwise to promote the sale, use or 79118611Snjl * other dealings in products derived from or relating to the Covered Code 80118611Snjl * without prior written authorization from Intel. 81118611Snjl * 82118611Snjl * 4. Disclaimer and Export Compliance 83118611Snjl * 84118611Snjl * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 85118611Snjl * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 86118611Snjl * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 87118611Snjl * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 88118611Snjl * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 89118611Snjl * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 90118611Snjl * PARTICULAR PURPOSE. 91118611Snjl * 92118611Snjl * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 93118611Snjl * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 94118611Snjl * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 95118611Snjl * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 96118611Snjl * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 97118611Snjl * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 98118611Snjl * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 99118611Snjl * LIMITED REMEDY. 100118611Snjl * 101118611Snjl * 4.3. Licensee shall not export, either directly or indirectly, any of this 102118611Snjl * software or system incorporating such software without first obtaining any 103118611Snjl * required license or other approval from the U. S. Department of Commerce or 104118611Snjl * any other agency or department of the United States Government. In the 105118611Snjl * event Licensee exports any such software from the United States or 106118611Snjl * re-exports any such software from a foreign destination, Licensee shall 107118611Snjl * ensure that the distribution and export/re-export of the software is in 108118611Snjl * compliance with all laws, regulations, orders, or other restrictions of the 109118611Snjl * U.S. Export Administration Regulations. Licensee agrees that neither it nor 110118611Snjl * any of its subsidiaries will export/re-export any technical data, process, 111118611Snjl * software, or service, directly or indirectly, to any country for which the 112118611Snjl * United States government or any agency thereof requires an export license, 113118611Snjl * other governmental approval, or letter of assurance, without first obtaining 114118611Snjl * such license, approval or letter. 115118611Snjl * 116118611Snjl *****************************************************************************/ 117118611Snjl 118118611Snjl 119151937Sjkim#include <contrib/dev/acpica/compiler/aslcompiler.h> 120118611Snjl#include "aslcompiler.y.h" 121151937Sjkim#include <contrib/dev/acpica/acparser.h> 122151937Sjkim#include <contrib/dev/acpica/amlcode.h> 123118611Snjl 124118611Snjl#include <ctype.h> 125118611Snjl 126118611Snjl#define _COMPONENT ACPI_COMPILER 127118611Snjl ACPI_MODULE_NAME ("aslanalyze") 128118611Snjl 129151937Sjkim/* Local prototypes */ 130118611Snjl 131151937Sjkimstatic UINT32 132151937SjkimAnMapArgTypeToBtype ( 133151937Sjkim UINT32 ArgType); 134151937Sjkim 135151937Sjkimstatic UINT32 136151937SjkimAnMapEtypeToBtype ( 137151937Sjkim UINT32 Etype); 138151937Sjkim 139151937Sjkimstatic void 140151937SjkimAnFormatBtype ( 141151937Sjkim char *Buffer, 142151937Sjkim UINT32 Btype); 143151937Sjkim 144151937Sjkimstatic UINT32 145151937SjkimAnGetBtype ( 146151937Sjkim ACPI_PARSE_OBJECT *Op); 147151937Sjkim 148151937Sjkimstatic UINT32 149151937SjkimAnCheckForReservedName ( 150151937Sjkim ACPI_PARSE_OBJECT *Op, 151151937Sjkim char *Name); 152151937Sjkim 153151937Sjkimstatic void 154151937SjkimAnCheckForReservedMethod ( 155151937Sjkim ACPI_PARSE_OBJECT *Op, 156151937Sjkim ASL_METHOD_INFO *MethodInfo); 157151937Sjkim 158151937Sjkimstatic UINT32 159151937SjkimAnMapObjTypeToBtype ( 160151937Sjkim ACPI_PARSE_OBJECT *Op); 161151937Sjkim 162151937Sjkimstatic BOOLEAN 163151937SjkimAnLastStatementIsReturn ( 164151937Sjkim ACPI_PARSE_OBJECT *Op); 165151937Sjkim 166151937Sjkimstatic void 167151937SjkimAnCheckMethodReturnValue ( 168151937Sjkim ACPI_PARSE_OBJECT *Op, 169151937Sjkim const ACPI_OPCODE_INFO *OpInfo, 170151937Sjkim ACPI_PARSE_OBJECT *ArgOp, 171151937Sjkim UINT32 RequiredBtypes, 172151937Sjkim UINT32 ThisNodeBtype); 173151937Sjkim 174167802Sjkimstatic BOOLEAN 175167802SjkimAnIsInternalMethod ( 176167802Sjkim ACPI_PARSE_OBJECT *Op); 177151937Sjkim 178167802Sjkimstatic UINT32 179167802SjkimAnGetInternalMethodReturnType ( 180167802Sjkim ACPI_PARSE_OBJECT *Op); 181167802Sjkim 182167802Sjkim 183118611Snjl/******************************************************************************* 184118611Snjl * 185167802Sjkim * FUNCTION: AnIsInternalMethod 186167802Sjkim * 187167802Sjkim * PARAMETERS: Op - Current op 188167802Sjkim * 189167802Sjkim * RETURN: Boolean 190167802Sjkim * 191167802Sjkim * DESCRIPTION: Check for an internal control method. 192167802Sjkim * 193167802Sjkim ******************************************************************************/ 194167802Sjkim 195167802Sjkimstatic BOOLEAN 196167802SjkimAnIsInternalMethod ( 197167802Sjkim ACPI_PARSE_OBJECT *Op) 198167802Sjkim{ 199167802Sjkim 200167802Sjkim if ((!ACPI_STRCMP (Op->Asl.ExternalName, "\\_OSI")) || 201167802Sjkim (!ACPI_STRCMP (Op->Asl.ExternalName, "_OSI"))) 202167802Sjkim { 203167802Sjkim return (TRUE); 204167802Sjkim } 205167802Sjkim 206167802Sjkim return (FALSE); 207167802Sjkim} 208167802Sjkim 209167802Sjkim 210167802Sjkim/******************************************************************************* 211167802Sjkim * 212167802Sjkim * FUNCTION: AnGetInternalMethodReturnType 213167802Sjkim * 214167802Sjkim * PARAMETERS: Op - Current op 215167802Sjkim * 216167802Sjkim * RETURN: Btype 217167802Sjkim * 218167802Sjkim * DESCRIPTION: Get the return type of an internal method 219167802Sjkim * 220167802Sjkim ******************************************************************************/ 221167802Sjkim 222167802Sjkimstatic UINT32 223167802SjkimAnGetInternalMethodReturnType ( 224167802Sjkim ACPI_PARSE_OBJECT *Op) 225167802Sjkim{ 226167802Sjkim 227167802Sjkim if ((!ACPI_STRCMP (Op->Asl.ExternalName, "\\_OSI")) || 228167802Sjkim (!ACPI_STRCMP (Op->Asl.ExternalName, "_OSI"))) 229167802Sjkim { 230167802Sjkim return (ACPI_BTYPE_STRING); 231167802Sjkim } 232167802Sjkim 233167802Sjkim return (0); 234167802Sjkim} 235167802Sjkim 236167802Sjkim 237167802Sjkim/******************************************************************************* 238167802Sjkim * 239118611Snjl * FUNCTION: AnMapArgTypeToBtype 240118611Snjl * 241118611Snjl * PARAMETERS: ArgType - The ARGI required type(s) for this argument, 242118611Snjl * from the opcode info table 243118611Snjl * 244118611Snjl * RETURN: The corresponding Bit-encoded types 245118611Snjl * 246118611Snjl * DESCRIPTION: Convert an encoded ARGI required argument type code into a 247167802Sjkim * bitfield type code. Implements the implicit source conversion 248118611Snjl * rules. 249118611Snjl * 250118611Snjl ******************************************************************************/ 251118611Snjl 252151937Sjkimstatic UINT32 253118611SnjlAnMapArgTypeToBtype ( 254118611Snjl UINT32 ArgType) 255118611Snjl{ 256118611Snjl 257118611Snjl switch (ArgType) 258118611Snjl { 259118611Snjl 260118611Snjl /* Simple types */ 261118611Snjl 262118611Snjl case ARGI_ANYTYPE: 263118611Snjl return (ACPI_BTYPE_OBJECTS_AND_REFS); 264118611Snjl 265118611Snjl case ARGI_PACKAGE: 266118611Snjl return (ACPI_BTYPE_PACKAGE); 267118611Snjl 268118611Snjl case ARGI_EVENT: 269118611Snjl return (ACPI_BTYPE_EVENT); 270118611Snjl 271118611Snjl case ARGI_MUTEX: 272118611Snjl return (ACPI_BTYPE_MUTEX); 273118611Snjl 274118611Snjl case ARGI_DDBHANDLE: 275118611Snjl return (ACPI_BTYPE_DDB_HANDLE); 276118611Snjl 277118611Snjl /* Interchangeable types */ 278118611Snjl /* 279118611Snjl * Source conversion rules: 280118611Snjl * Integer, String, and Buffer are all interchangeable 281118611Snjl */ 282118611Snjl case ARGI_INTEGER: 283118611Snjl case ARGI_STRING: 284118611Snjl case ARGI_BUFFER: 285118611Snjl case ARGI_BUFFER_OR_STRING: 286118611Snjl case ARGI_COMPUTEDATA: 287118611Snjl return (ACPI_BTYPE_COMPUTE_DATA); 288118611Snjl 289118611Snjl /* References */ 290118611Snjl 291118611Snjl case ARGI_INTEGER_REF: 292118611Snjl return (ACPI_BTYPE_INTEGER); 293118611Snjl 294118611Snjl case ARGI_OBJECT_REF: 295118611Snjl return (ACPI_BTYPE_ALL_OBJECTS); 296118611Snjl 297118611Snjl case ARGI_DEVICE_REF: 298118611Snjl return (ACPI_BTYPE_DEVICE_OBJECTS); 299118611Snjl 300118611Snjl case ARGI_REFERENCE: 301118611Snjl return (ACPI_BTYPE_REFERENCE); 302118611Snjl 303118611Snjl case ARGI_TARGETREF: 304118611Snjl case ARGI_FIXED_TARGET: 305118611Snjl case ARGI_SIMPLE_TARGET: 306118611Snjl return (ACPI_BTYPE_OBJECTS_AND_REFS); 307118611Snjl 308118611Snjl /* Complex types */ 309118611Snjl 310118611Snjl case ARGI_DATAOBJECT: 311118611Snjl 312151937Sjkim /* 313151937Sjkim * Buffer, string, package or reference to a Op - 314151937Sjkim * Used only by SizeOf operator 315151937Sjkim */ 316151937Sjkim return (ACPI_BTYPE_STRING | ACPI_BTYPE_BUFFER | 317151937Sjkim ACPI_BTYPE_PACKAGE | ACPI_BTYPE_REFERENCE); 318118611Snjl 319118611Snjl case ARGI_COMPLEXOBJ: 320118611Snjl 321118611Snjl /* Buffer, String, or package */ 322118611Snjl 323118611Snjl return (ACPI_BTYPE_STRING | ACPI_BTYPE_BUFFER | ACPI_BTYPE_PACKAGE); 324118611Snjl 325118611Snjl case ARGI_REF_OR_STRING: 326118611Snjl return (ACPI_BTYPE_STRING | ACPI_BTYPE_REFERENCE); 327118611Snjl 328167802Sjkim case ARGI_REGION_OR_BUFFER: 329118611Snjl 330167802Sjkim /* Used by Load() only. Allow buffers in addition to regions/fields */ 331167802Sjkim 332167802Sjkim return (ACPI_BTYPE_REGION | ACPI_BTYPE_BUFFER | ACPI_BTYPE_FIELD_UNIT); 333167802Sjkim 334151937Sjkim case ARGI_DATAREFOBJ: 335151937Sjkim return (ACPI_BTYPE_INTEGER |ACPI_BTYPE_STRING | ACPI_BTYPE_BUFFER | 336151937Sjkim ACPI_BTYPE_PACKAGE | ACPI_BTYPE_REFERENCE | ACPI_BTYPE_DDB_HANDLE); 337151937Sjkim 338118611Snjl default: 339118611Snjl break; 340118611Snjl } 341118611Snjl 342118611Snjl return (ACPI_BTYPE_OBJECTS_AND_REFS); 343118611Snjl} 344118611Snjl 345118611Snjl 346118611Snjl/******************************************************************************* 347118611Snjl * 348118611Snjl * FUNCTION: AnMapEtypeToBtype 349118611Snjl * 350118611Snjl * PARAMETERS: Etype - Encoded ACPI Type 351118611Snjl * 352118611Snjl * RETURN: Btype corresponding to the Etype 353118611Snjl * 354118611Snjl * DESCRIPTION: Convert an encoded ACPI type to a bitfield type applying the 355167802Sjkim * operand conversion rules. In other words, returns the type(s) 356118611Snjl * this Etype is implicitly converted to during interpretation. 357118611Snjl * 358118611Snjl ******************************************************************************/ 359118611Snjl 360151937Sjkimstatic UINT32 361118611SnjlAnMapEtypeToBtype ( 362151937Sjkim UINT32 Etype) 363118611Snjl{ 364118611Snjl 365118611Snjl 366118611Snjl if (Etype == ACPI_TYPE_ANY) 367118611Snjl { 368118611Snjl return ACPI_BTYPE_OBJECTS_AND_REFS; 369118611Snjl } 370118611Snjl 371118611Snjl /* Try the standard ACPI data types */ 372118611Snjl 373118611Snjl if (Etype <= ACPI_TYPE_EXTERNAL_MAX) 374118611Snjl { 375118611Snjl /* 376118611Snjl * This switch statement implements the allowed operand conversion 377118611Snjl * rules as per the "ASL Data Types" section of the ACPI 378118611Snjl * specification. 379118611Snjl */ 380118611Snjl switch (Etype) 381118611Snjl { 382118611Snjl case ACPI_TYPE_INTEGER: 383118611Snjl return (ACPI_BTYPE_COMPUTE_DATA | ACPI_BTYPE_DDB_HANDLE); 384118611Snjl 385118611Snjl case ACPI_TYPE_STRING: 386118611Snjl case ACPI_TYPE_BUFFER: 387118611Snjl return (ACPI_BTYPE_COMPUTE_DATA); 388118611Snjl 389118611Snjl case ACPI_TYPE_PACKAGE: 390118611Snjl return (ACPI_BTYPE_PACKAGE); 391118611Snjl 392118611Snjl case ACPI_TYPE_FIELD_UNIT: 393118611Snjl return (ACPI_BTYPE_COMPUTE_DATA | ACPI_BTYPE_FIELD_UNIT); 394118611Snjl 395118611Snjl case ACPI_TYPE_BUFFER_FIELD: 396118611Snjl return (ACPI_BTYPE_COMPUTE_DATA | ACPI_BTYPE_BUFFER_FIELD); 397118611Snjl 398118611Snjl case ACPI_TYPE_DDB_HANDLE: 399118611Snjl return (ACPI_BTYPE_INTEGER | ACPI_BTYPE_DDB_HANDLE); 400118611Snjl 401118611Snjl case ACPI_BTYPE_DEBUG_OBJECT: 402118611Snjl 403118611Snjl /* Cannot be used as a source operand */ 404118611Snjl 405118611Snjl return (0); 406118611Snjl 407118611Snjl default: 408118611Snjl return (1 << (Etype - 1)); 409118611Snjl } 410118611Snjl } 411118611Snjl 412118611Snjl /* Try the internal data types */ 413118611Snjl 414118611Snjl switch (Etype) 415118611Snjl { 416118611Snjl case ACPI_TYPE_LOCAL_REGION_FIELD: 417118611Snjl case ACPI_TYPE_LOCAL_BANK_FIELD: 418118611Snjl case ACPI_TYPE_LOCAL_INDEX_FIELD: 419118611Snjl 420118611Snjl /* Named fields can be either Integer/Buffer/String */ 421118611Snjl 422118611Snjl return (ACPI_BTYPE_COMPUTE_DATA | ACPI_BTYPE_FIELD_UNIT); 423118611Snjl 424118611Snjl case ACPI_TYPE_LOCAL_ALIAS: 425118611Snjl 426118611Snjl return (ACPI_BTYPE_INTEGER); 427118611Snjl 428118611Snjl 429118611Snjl case ACPI_TYPE_LOCAL_RESOURCE: 430118611Snjl case ACPI_TYPE_LOCAL_RESOURCE_FIELD: 431118611Snjl 432118611Snjl return (ACPI_BTYPE_REFERENCE); 433118611Snjl 434118611Snjl default: 435118611Snjl printf ("Unhandled encoded type: %X\n", Etype); 436118611Snjl return (0); 437118611Snjl } 438118611Snjl} 439118611Snjl 440118611Snjl 441118611Snjl/******************************************************************************* 442118611Snjl * 443118611Snjl * FUNCTION: AnFormatBtype 444118611Snjl * 445118611Snjl * PARAMETERS: Btype - Bitfield of ACPI types 446118611Snjl * Buffer - Where to put the ascii string 447118611Snjl * 448118611Snjl * RETURN: None. 449118611Snjl * 450118611Snjl * DESCRIPTION: Convert a Btype to a string of ACPI types 451118611Snjl * 452118611Snjl ******************************************************************************/ 453118611Snjl 454151937Sjkimstatic void 455118611SnjlAnFormatBtype ( 456151937Sjkim char *Buffer, 457151937Sjkim UINT32 Btype) 458118611Snjl{ 459151937Sjkim UINT32 Type; 460151937Sjkim BOOLEAN First = TRUE; 461118611Snjl 462118611Snjl 463118611Snjl *Buffer = 0; 464118611Snjl 465118611Snjl if (Btype == 0) 466118611Snjl { 467118611Snjl strcat (Buffer, "NoReturnValue"); 468118611Snjl return; 469118611Snjl } 470118611Snjl 471151937Sjkim for (Type = 1; Type <= ACPI_TYPE_EXTERNAL_MAX; Type++) 472118611Snjl { 473118611Snjl if (Btype & 0x00000001) 474118611Snjl { 475118611Snjl if (!First) 476118611Snjl { 477118611Snjl strcat (Buffer, "|"); 478118611Snjl } 479118611Snjl First = FALSE; 480118611Snjl strcat (Buffer, AcpiUtGetTypeName (Type)); 481118611Snjl } 482118611Snjl Btype >>= 1; 483118611Snjl } 484118611Snjl 485118611Snjl if (Btype & 0x00000001) 486118611Snjl { 487118611Snjl if (!First) 488118611Snjl { 489118611Snjl strcat (Buffer, "|"); 490118611Snjl } 491118611Snjl First = FALSE; 492118611Snjl strcat (Buffer, "Reference"); 493118611Snjl } 494118611Snjl 495118611Snjl Btype >>= 1; 496118611Snjl if (Btype & 0x00000001) 497118611Snjl { 498118611Snjl if (!First) 499118611Snjl { 500118611Snjl strcat (Buffer, "|"); 501118611Snjl } 502118611Snjl First = FALSE; 503118611Snjl strcat (Buffer, "Resource"); 504118611Snjl } 505118611Snjl} 506118611Snjl 507118611Snjl 508118611Snjl/******************************************************************************* 509118611Snjl * 510118611Snjl * FUNCTION: AnGetBtype 511118611Snjl * 512118611Snjl * PARAMETERS: Op - Parse node whose type will be returned. 513118611Snjl * 514118611Snjl * RETURN: The Btype associated with the Op. 515118611Snjl * 516118611Snjl * DESCRIPTION: Get the (bitfield) ACPI type associated with the parse node. 517118611Snjl * Handles the case where the node is a name or method call and 518118611Snjl * the actual type must be obtained from the namespace node. 519118611Snjl * 520118611Snjl ******************************************************************************/ 521118611Snjl 522151937Sjkimstatic UINT32 523118611SnjlAnGetBtype ( 524118611Snjl ACPI_PARSE_OBJECT *Op) 525118611Snjl{ 526118611Snjl ACPI_NAMESPACE_NODE *Node; 527118611Snjl ACPI_PARSE_OBJECT *ReferencedNode; 528118611Snjl UINT32 ThisNodeBtype = 0; 529118611Snjl 530118611Snjl 531118611Snjl if ((Op->Asl.ParseOpcode == PARSEOP_NAMESEG) || 532118611Snjl (Op->Asl.ParseOpcode == PARSEOP_NAMESTRING) || 533118611Snjl (Op->Asl.ParseOpcode == PARSEOP_METHODCALL)) 534118611Snjl { 535118611Snjl Node = Op->Asl.Node; 536118611Snjl if (!Node) 537118611Snjl { 538118611Snjl DbgPrint (ASL_DEBUG_OUTPUT, 539138287Smarks "No attached Nsnode: [%s] at line %d name [%s], ignoring typecheck\n", 540138287Smarks Op->Asl.ParseOpName, Op->Asl.LineNumber, 541138287Smarks Op->Asl.ExternalName); 542118611Snjl return ACPI_UINT32_MAX; 543118611Snjl } 544118611Snjl 545118611Snjl ThisNodeBtype = AnMapEtypeToBtype (Node->Type); 546151937Sjkim if (!ThisNodeBtype) 547151937Sjkim { 548167802Sjkim AslError (ASL_ERROR, ASL_MSG_COMPILER_INTERNAL, Op, 549167802Sjkim "could not map type"); 550151937Sjkim } 551118611Snjl 552118611Snjl /* 553118611Snjl * Since it was a named reference, enable the 554118611Snjl * reference bit also 555118611Snjl */ 556118611Snjl ThisNodeBtype |= ACPI_BTYPE_REFERENCE; 557118611Snjl 558118611Snjl if (Op->Asl.ParseOpcode == PARSEOP_METHODCALL) 559118611Snjl { 560151937Sjkim ReferencedNode = Node->Op; 561118611Snjl if (!ReferencedNode) 562118611Snjl { 563167802Sjkim /* Check for an internal method */ 564167802Sjkim 565167802Sjkim if (AnIsInternalMethod (Op)) 566167802Sjkim { 567167802Sjkim return (AnGetInternalMethodReturnType (Op)); 568167802Sjkim } 569167802Sjkim 570167802Sjkim AslError (ASL_ERROR, ASL_MSG_COMPILER_INTERNAL, Op, 571167802Sjkim "null Op pointer"); 572167802Sjkim return ACPI_UINT32_MAX; 573118611Snjl } 574118611Snjl 575118611Snjl if (ReferencedNode->Asl.CompileFlags & NODE_METHOD_TYPED) 576118611Snjl { 577118611Snjl ThisNodeBtype = ReferencedNode->Asl.AcpiBtype; 578118611Snjl } 579118611Snjl else 580118611Snjl { 581118611Snjl return (ACPI_UINT32_MAX -1); 582118611Snjl } 583118611Snjl } 584118611Snjl } 585118611Snjl else 586118611Snjl { 587118611Snjl ThisNodeBtype = Op->Asl.AcpiBtype; 588118611Snjl } 589118611Snjl 590118611Snjl return (ThisNodeBtype); 591118611Snjl} 592118611Snjl 593118611Snjl 594118611Snjl/******************************************************************************* 595118611Snjl * 596118611Snjl * FUNCTION: AnCheckForReservedName 597118611Snjl * 598118611Snjl * PARAMETERS: Op - A parse node 599118611Snjl * Name - NameSeg to check 600118611Snjl * 601118611Snjl * RETURN: None 602118611Snjl * 603118611Snjl * DESCRIPTION: Check a NameSeg against the reserved list. 604118611Snjl * 605118611Snjl ******************************************************************************/ 606118611Snjl 607151937Sjkimstatic UINT32 608118611SnjlAnCheckForReservedName ( 609118611Snjl ACPI_PARSE_OBJECT *Op, 610118611Snjl char *Name) 611118611Snjl{ 612118611Snjl UINT32 i; 613118611Snjl 614118611Snjl 615118611Snjl if (Name[0] == 0) 616118611Snjl { 617151937Sjkim AcpiOsPrintf ("Found a null name, external = %s\n", 618151937Sjkim Op->Asl.ExternalName); 619118611Snjl } 620118611Snjl 621118611Snjl /* All reserved names are prefixed with a single underscore */ 622118611Snjl 623118611Snjl if (Name[0] != '_') 624118611Snjl { 625118611Snjl return (ACPI_NOT_RESERVED_NAME); 626118611Snjl } 627118611Snjl 628118611Snjl /* Check for a standard reserved method name */ 629118611Snjl 630118611Snjl for (i = 0; ReservedMethods[i].Name; i++) 631118611Snjl { 632167802Sjkim if (ACPI_COMPARE_NAME (Name, ReservedMethods[i].Name)) 633118611Snjl { 634118611Snjl if (ReservedMethods[i].Flags & ASL_RSVD_SCOPE) 635118611Snjl { 636151937Sjkim AslError (ASL_ERROR, ASL_MSG_RESERVED_WORD, Op, 637151937Sjkim Op->Asl.ExternalName); 638118611Snjl return (ACPI_PREDEFINED_NAME); 639118611Snjl } 640118611Snjl else if (ReservedMethods[i].Flags & ASL_RSVD_RESOURCE_NAME) 641118611Snjl { 642151937Sjkim AslError (ASL_ERROR, ASL_MSG_RESERVED_WORD, Op, 643151937Sjkim Op->Asl.ExternalName); 644118611Snjl return (ACPI_PREDEFINED_NAME); 645118611Snjl } 646118611Snjl 647118611Snjl /* Return index into reserved array */ 648118611Snjl 649118611Snjl return i; 650118611Snjl } 651118611Snjl } 652118611Snjl 653118611Snjl /* 654118611Snjl * Now check for the "special" reserved names -- 655118611Snjl * GPE: _Lxx 656118611Snjl * GPE: _Exx 657118611Snjl * EC: _Qxx 658118611Snjl */ 659118611Snjl if ((Name[1] == 'L') || 660118611Snjl (Name[1] == 'E') || 661118611Snjl (Name[1] == 'Q')) 662118611Snjl { 663118611Snjl /* The next two characters must be hex digits */ 664118611Snjl 665118611Snjl if ((isxdigit (Name[2])) && 666118611Snjl (isxdigit (Name[3]))) 667118611Snjl { 668118611Snjl return (ACPI_EVENT_RESERVED_NAME); 669118611Snjl } 670118611Snjl } 671118611Snjl 672118611Snjl 673118611Snjl /* Check for the names reserved for the compiler itself: _T_x */ 674118611Snjl 675118611Snjl else if ((Op->Asl.ExternalName[1] == 'T') && 676118611Snjl (Op->Asl.ExternalName[2] == '_')) 677118611Snjl { 678138287Smarks /* Ignore if actually emitted by the compiler */ 679138287Smarks 680138287Smarks if (Op->Asl.CompileFlags & NODE_COMPILER_EMITTED) 681138287Smarks { 682138287Smarks return (ACPI_NOT_RESERVED_NAME); 683138287Smarks } 684138287Smarks 685118611Snjl AslError (ASL_ERROR, ASL_MSG_RESERVED_WORD, Op, Op->Asl.ExternalName); 686118611Snjl return (ACPI_COMPILER_RESERVED_NAME); 687118611Snjl } 688118611Snjl 689118611Snjl /* 690167802Sjkim * The name didn't match any of the known reserved names. Flag it as a 691118611Snjl * warning, since the entire namespace starting with an underscore is 692118611Snjl * reserved by the ACPI spec. 693118611Snjl */ 694151937Sjkim AslError (ASL_WARNING, ASL_MSG_UNKNOWN_RESERVED_NAME, Op, 695151937Sjkim Op->Asl.ExternalName); 696118611Snjl 697118611Snjl return (ACPI_NOT_RESERVED_NAME); 698118611Snjl} 699118611Snjl 700118611Snjl 701118611Snjl/******************************************************************************* 702118611Snjl * 703118611Snjl * FUNCTION: AnCheckForReservedMethod 704118611Snjl * 705118611Snjl * PARAMETERS: Op - A parse node of type "METHOD". 706118611Snjl * MethodInfo - Saved info about this method 707118611Snjl * 708118611Snjl * RETURN: None 709118611Snjl * 710118611Snjl * DESCRIPTION: If method is a reserved name, check that the number of arguments 711118611Snjl * and the return type (returns a value or not) is correct. 712118611Snjl * 713118611Snjl ******************************************************************************/ 714118611Snjl 715151937Sjkimstatic void 716118611SnjlAnCheckForReservedMethod ( 717118611Snjl ACPI_PARSE_OBJECT *Op, 718118611Snjl ASL_METHOD_INFO *MethodInfo) 719118611Snjl{ 720118611Snjl UINT32 Index; 721118611Snjl 722118611Snjl 723118611Snjl /* Check for a match against the reserved name list */ 724118611Snjl 725118611Snjl Index = AnCheckForReservedName (Op, Op->Asl.NameSeg); 726118611Snjl 727118611Snjl switch (Index) 728118611Snjl { 729118611Snjl case ACPI_NOT_RESERVED_NAME: 730118611Snjl case ACPI_PREDEFINED_NAME: 731118611Snjl case ACPI_COMPILER_RESERVED_NAME: 732118611Snjl 733118611Snjl /* Just return, nothing to do */ 734118611Snjl break; 735118611Snjl 736118611Snjl 737118611Snjl case ACPI_EVENT_RESERVED_NAME: 738118611Snjl 739118611Snjl Gbl_ReservedMethods++; 740118611Snjl 741118611Snjl /* NumArguments must be zero for all _Lxx, _Exx, and _Qxx methods */ 742118611Snjl 743118611Snjl if (MethodInfo->NumArguments != 0) 744118611Snjl { 745167802Sjkim sprintf (MsgBuffer, "%s requires %d", 746118611Snjl Op->Asl.ExternalName, 0); 747118611Snjl 748118611Snjl AslError (ASL_WARNING, ASL_MSG_RESERVED_ARG_COUNT_HI, Op, MsgBuffer); 749118611Snjl } 750118611Snjl break; 751118611Snjl 752118611Snjl 753118611Snjl default: 754118611Snjl 755118611Snjl Gbl_ReservedMethods++; 756118611Snjl 757118611Snjl /* Matched a reserved method name */ 758118611Snjl 759118611Snjl if (MethodInfo->NumArguments != ReservedMethods[Index].NumArguments) 760118611Snjl { 761167802Sjkim sprintf (MsgBuffer, "%s requires %d", 762118611Snjl ReservedMethods[Index].Name, 763118611Snjl ReservedMethods[Index].NumArguments); 764118611Snjl 765118611Snjl if (MethodInfo->NumArguments > ReservedMethods[Index].NumArguments) 766118611Snjl { 767151937Sjkim AslError (ASL_WARNING, ASL_MSG_RESERVED_ARG_COUNT_HI, Op, 768151937Sjkim MsgBuffer); 769118611Snjl } 770118611Snjl else 771118611Snjl { 772151937Sjkim AslError (ASL_WARNING, ASL_MSG_RESERVED_ARG_COUNT_LO, Op, 773151937Sjkim MsgBuffer); 774118611Snjl } 775118611Snjl } 776118611Snjl 777118611Snjl if (MethodInfo->NumReturnNoValue && 778118611Snjl ReservedMethods[Index].Flags & ASL_RSVD_RETURN_VALUE) 779118611Snjl { 780118611Snjl sprintf (MsgBuffer, "%s", ReservedMethods[Index].Name); 781118611Snjl 782118611Snjl AslError (ASL_WARNING, ASL_MSG_RESERVED_RETURN_VALUE, Op, MsgBuffer); 783118611Snjl } 784118611Snjl break; 785118611Snjl } 786118611Snjl} 787118611Snjl 788118611Snjl 789151937Sjkim/******************************************************************************* 790151937Sjkim * 791151937Sjkim * FUNCTION: AnMapObjTypeToBtype 792151937Sjkim * 793151937Sjkim * PARAMETERS: Op - A parse node 794151937Sjkim * 795151937Sjkim * RETURN: A Btype 796151937Sjkim * 797151937Sjkim * DESCRIPTION: Map object to the associated "Btype" 798151937Sjkim * 799151937Sjkim ******************************************************************************/ 800151937Sjkim 801151937Sjkimstatic UINT32 802138287SmarksAnMapObjTypeToBtype ( 803138287Smarks ACPI_PARSE_OBJECT *Op) 804138287Smarks{ 805138287Smarks 806138287Smarks switch (Op->Asl.ParseOpcode) 807138287Smarks { 808138287Smarks case PARSEOP_OBJECTTYPE_BFF: /* "BuffFieldObj" */ 809138287Smarks return (ACPI_BTYPE_BUFFER_FIELD); 810138287Smarks 811138287Smarks case PARSEOP_OBJECTTYPE_BUF: /* "BuffObj" */ 812138287Smarks return (ACPI_BTYPE_BUFFER); 813138287Smarks 814138287Smarks case PARSEOP_OBJECTTYPE_DDB: /* "DDBHandleObj" */ 815138287Smarks return (ACPI_BTYPE_DDB_HANDLE); 816138287Smarks 817138287Smarks case PARSEOP_OBJECTTYPE_DEV: /* "DeviceObj" */ 818138287Smarks return (ACPI_BTYPE_DEVICE); 819138287Smarks 820138287Smarks case PARSEOP_OBJECTTYPE_EVT: /* "EventObj" */ 821138287Smarks return (ACPI_BTYPE_EVENT); 822138287Smarks 823138287Smarks case PARSEOP_OBJECTTYPE_FLD: /* "FieldUnitObj" */ 824138287Smarks return (ACPI_BTYPE_FIELD_UNIT); 825138287Smarks 826138287Smarks case PARSEOP_OBJECTTYPE_INT: /* "IntObj" */ 827138287Smarks return (ACPI_BTYPE_INTEGER); 828138287Smarks 829138287Smarks case PARSEOP_OBJECTTYPE_MTH: /* "MethodObj" */ 830138287Smarks return (ACPI_BTYPE_METHOD); 831138287Smarks 832138287Smarks case PARSEOP_OBJECTTYPE_MTX: /* "MutexObj" */ 833138287Smarks return (ACPI_BTYPE_MUTEX); 834138287Smarks 835138287Smarks case PARSEOP_OBJECTTYPE_OPR: /* "OpRegionObj" */ 836138287Smarks return (ACPI_BTYPE_REGION); 837138287Smarks 838138287Smarks case PARSEOP_OBJECTTYPE_PKG: /* "PkgObj" */ 839138287Smarks return (ACPI_BTYPE_PACKAGE); 840138287Smarks 841138287Smarks case PARSEOP_OBJECTTYPE_POW: /* "PowerResObj" */ 842138287Smarks return (ACPI_BTYPE_POWER); 843138287Smarks 844138287Smarks case PARSEOP_OBJECTTYPE_STR: /* "StrObj" */ 845138287Smarks return (ACPI_BTYPE_STRING); 846138287Smarks 847138287Smarks case PARSEOP_OBJECTTYPE_THZ: /* "ThermalZoneObj" */ 848138287Smarks return (ACPI_BTYPE_THERMAL); 849138287Smarks 850138287Smarks case PARSEOP_OBJECTTYPE_UNK: /* "UnknownObj" */ 851138287Smarks return (ACPI_BTYPE_OBJECTS_AND_REFS); 852138287Smarks 853138287Smarks default: 854138287Smarks return (0); 855138287Smarks } 856138287Smarks} 857138287Smarks 858138287Smarks 859118611Snjl/******************************************************************************* 860118611Snjl * 861118611Snjl * FUNCTION: AnMethodAnalysisWalkBegin 862118611Snjl * 863118611Snjl * PARAMETERS: ASL_WALK_CALLBACK 864118611Snjl * 865118611Snjl * RETURN: Status 866118611Snjl * 867167802Sjkim * DESCRIPTION: Descending callback for the analysis walk. Check methods for: 868118611Snjl * 1) Initialized local variables 869118611Snjl * 2) Valid arguments 870118611Snjl * 3) Return types 871118611Snjl * 872118611Snjl ******************************************************************************/ 873118611Snjl 874118611SnjlACPI_STATUS 875118611SnjlAnMethodAnalysisWalkBegin ( 876118611Snjl ACPI_PARSE_OBJECT *Op, 877118611Snjl UINT32 Level, 878118611Snjl void *Context) 879118611Snjl{ 880118611Snjl ASL_ANALYSIS_WALK_INFO *WalkInfo = (ASL_ANALYSIS_WALK_INFO *) Context; 881118611Snjl ASL_METHOD_INFO *MethodInfo = WalkInfo->MethodStack; 882118611Snjl ACPI_PARSE_OBJECT *Next; 883118611Snjl UINT32 RegisterNumber; 884118611Snjl UINT32 i; 885118611Snjl char LocalName[] = "Local0"; 886118611Snjl char ArgName[] = "Arg0"; 887138287Smarks ACPI_PARSE_OBJECT *ArgNode; 888138287Smarks ACPI_PARSE_OBJECT *NextType; 889138287Smarks ACPI_PARSE_OBJECT *NextParamType; 890151937Sjkim UINT8 ActualArgs = 0; 891118611Snjl 892118611Snjl 893118611Snjl switch (Op->Asl.ParseOpcode) 894118611Snjl { 895118611Snjl case PARSEOP_METHOD: 896118611Snjl 897118611Snjl TotalMethods++; 898118611Snjl 899151937Sjkim /* Create and init method info */ 900151937Sjkim 901118611Snjl MethodInfo = UtLocalCalloc (sizeof (ASL_METHOD_INFO)); 902118611Snjl MethodInfo->Next = WalkInfo->MethodStack; 903118611Snjl MethodInfo->Op = Op; 904118611Snjl 905118611Snjl WalkInfo->MethodStack = MethodInfo; 906118611Snjl 907138287Smarks /* Get the name node, ignored here */ 908138287Smarks 909138287Smarks Next = Op->Asl.Child; 910138287Smarks 911118611Snjl /* Get the NumArguments node */ 912118611Snjl 913118611Snjl Next = Next->Asl.Next; 914151937Sjkim MethodInfo->NumArguments = (UINT8) 915151937Sjkim (((UINT8) Next->Asl.Value.Integer) & 0x07); 916118611Snjl 917138287Smarks /* Get the SerializeRule and SyncLevel nodes, ignored here */ 918138287Smarks 919138287Smarks Next = Next->Asl.Next; 920138287Smarks Next = Next->Asl.Next; 921138287Smarks ArgNode = Next; 922138287Smarks 923138287Smarks /* Get the ReturnType node */ 924138287Smarks 925138287Smarks Next = Next->Asl.Next; 926138287Smarks 927138287Smarks NextType = Next->Asl.Child; 928138287Smarks while (NextType) 929138287Smarks { 930138287Smarks /* Get and map each of the ReturnTypes */ 931138287Smarks 932138287Smarks MethodInfo->ValidReturnTypes |= AnMapObjTypeToBtype (NextType); 933138287Smarks NextType->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG; 934138287Smarks NextType = NextType->Asl.Next; 935138287Smarks } 936138287Smarks 937138287Smarks /* Get the ParameterType node */ 938138287Smarks 939138287Smarks Next = Next->Asl.Next; 940138287Smarks 941138287Smarks NextType = Next->Asl.Child; 942138287Smarks while (NextType) 943138287Smarks { 944138287Smarks if (NextType->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG) 945138287Smarks { 946138287Smarks NextParamType = NextType->Asl.Child; 947138287Smarks while (NextParamType) 948138287Smarks { 949138287Smarks MethodInfo->ValidArgTypes[ActualArgs] |= AnMapObjTypeToBtype (NextParamType); 950138287Smarks NextParamType->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG; 951138287Smarks NextParamType = NextParamType->Asl.Next; 952138287Smarks } 953138287Smarks } 954138287Smarks else 955138287Smarks { 956151937Sjkim MethodInfo->ValidArgTypes[ActualArgs] = 957151937Sjkim AnMapObjTypeToBtype (NextType); 958138287Smarks NextType->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG; 959138287Smarks } 960138287Smarks 961138287Smarks ActualArgs++; 962138287Smarks NextType = NextType->Asl.Next; 963138287Smarks } 964138287Smarks 965138287Smarks if ((MethodInfo->NumArguments) && 966138287Smarks (MethodInfo->NumArguments != ActualArgs)) 967138287Smarks { 968138287Smarks /* error: Param list did not match number of args */ 969138287Smarks } 970138287Smarks 971138287Smarks /* Allow numarguments == 0 for Function() */ 972138287Smarks 973138287Smarks if ((!MethodInfo->NumArguments) && (ActualArgs)) 974138287Smarks { 975138287Smarks MethodInfo->NumArguments = ActualArgs; 976138287Smarks ArgNode->Asl.Value.Integer |= ActualArgs; 977138287Smarks } 978138287Smarks 979118611Snjl /* 980118611Snjl * Actual arguments are initialized at method entry. 981118611Snjl * All other ArgX "registers" can be used as locals, so we 982118611Snjl * track their initialization. 983118611Snjl */ 984118611Snjl for (i = 0; i < MethodInfo->NumArguments; i++) 985118611Snjl { 986118611Snjl MethodInfo->ArgInitialized[i] = TRUE; 987118611Snjl } 988118611Snjl break; 989118611Snjl 990118611Snjl 991118611Snjl case PARSEOP_METHODCALL: 992118611Snjl 993118611Snjl if (MethodInfo && 994118611Snjl (Op->Asl.Node == MethodInfo->Op->Asl.Node)) 995118611Snjl { 996118611Snjl AslError (ASL_REMARK, ASL_MSG_RECURSION, Op, Op->Asl.ExternalName); 997118611Snjl } 998118611Snjl break; 999118611Snjl 1000118611Snjl 1001118611Snjl case PARSEOP_LOCAL0: 1002118611Snjl case PARSEOP_LOCAL1: 1003118611Snjl case PARSEOP_LOCAL2: 1004118611Snjl case PARSEOP_LOCAL3: 1005118611Snjl case PARSEOP_LOCAL4: 1006118611Snjl case PARSEOP_LOCAL5: 1007118611Snjl case PARSEOP_LOCAL6: 1008118611Snjl case PARSEOP_LOCAL7: 1009118611Snjl 1010118611Snjl if (!MethodInfo) 1011118611Snjl { 1012151937Sjkim /* 1013151937Sjkim * Probably was an error in the method declaration, 1014151937Sjkim * no additional error here 1015151937Sjkim */ 1016167802Sjkim ACPI_WARNING ((AE_INFO, "%p, No parent method", Op)); 1017118611Snjl return (AE_ERROR); 1018118611Snjl } 1019118611Snjl 1020118611Snjl RegisterNumber = (Op->Asl.AmlOpcode & 0x000F); 1021118611Snjl 1022118611Snjl /* 1023118611Snjl * If the local is being used as a target, mark the local 1024118611Snjl * initialized 1025118611Snjl */ 1026118611Snjl if (Op->Asl.CompileFlags & NODE_IS_TARGET) 1027118611Snjl { 1028118611Snjl MethodInfo->LocalInitialized[RegisterNumber] = TRUE; 1029118611Snjl } 1030118611Snjl 1031118611Snjl /* 1032118611Snjl * Otherwise, this is a reference, check if the local 1033118611Snjl * has been previously initialized. 1034138287Smarks * 1035138287Smarks * The only operator that accepts an uninitialized value is ObjectType() 1036118611Snjl */ 1037138287Smarks else if ((!MethodInfo->LocalInitialized[RegisterNumber]) && 1038138287Smarks (Op->Asl.Parent->Asl.ParseOpcode != PARSEOP_OBJECTTYPE)) 1039118611Snjl { 1040118611Snjl LocalName[strlen (LocalName) -1] = (char) (RegisterNumber + 0x30); 1041118611Snjl AslError (ASL_ERROR, ASL_MSG_LOCAL_INIT, Op, LocalName); 1042118611Snjl } 1043118611Snjl break; 1044118611Snjl 1045118611Snjl 1046118611Snjl case PARSEOP_ARG0: 1047118611Snjl case PARSEOP_ARG1: 1048118611Snjl case PARSEOP_ARG2: 1049118611Snjl case PARSEOP_ARG3: 1050118611Snjl case PARSEOP_ARG4: 1051118611Snjl case PARSEOP_ARG5: 1052118611Snjl case PARSEOP_ARG6: 1053118611Snjl 1054118611Snjl if (!MethodInfo) 1055118611Snjl { 1056151937Sjkim /* 1057151937Sjkim * Probably was an error in the method declaration, 1058151937Sjkim * no additional error here 1059151937Sjkim */ 1060167802Sjkim ACPI_WARNING ((AE_INFO, "%p, No parent method", Op)); 1061118611Snjl return (AE_ERROR); 1062118611Snjl } 1063118611Snjl 1064118611Snjl RegisterNumber = (Op->Asl.AmlOpcode & 0x000F) - 8; 1065118611Snjl ArgName[strlen (ArgName) -1] = (char) (RegisterNumber + 0x30); 1066118611Snjl 1067118611Snjl /* 1068118611Snjl * If the Arg is being used as a target, mark the local 1069118611Snjl * initialized 1070118611Snjl */ 1071118611Snjl if (Op->Asl.CompileFlags & NODE_IS_TARGET) 1072118611Snjl { 1073118611Snjl MethodInfo->ArgInitialized[RegisterNumber] = TRUE; 1074118611Snjl } 1075118611Snjl 1076118611Snjl /* 1077118611Snjl * Otherwise, this is a reference, check if the Arg 1078118611Snjl * has been previously initialized. 1079138287Smarks * 1080138287Smarks * The only operator that accepts an uninitialized value is ObjectType() 1081118611Snjl */ 1082138287Smarks else if ((!MethodInfo->ArgInitialized[RegisterNumber]) && 1083138287Smarks (Op->Asl.Parent->Asl.ParseOpcode != PARSEOP_OBJECTTYPE)) 1084118611Snjl { 1085118611Snjl AslError (ASL_ERROR, ASL_MSG_ARG_INIT, Op, ArgName); 1086118611Snjl } 1087118611Snjl 1088118611Snjl /* Flag this arg if it is not a "real" argument to the method */ 1089118611Snjl 1090118611Snjl if (RegisterNumber >= MethodInfo->NumArguments) 1091118611Snjl { 1092118611Snjl AslError (ASL_REMARK, ASL_MSG_NOT_PARAMETER, Op, ArgName); 1093118611Snjl } 1094118611Snjl break; 1095118611Snjl 1096118611Snjl 1097118611Snjl case PARSEOP_RETURN: 1098118611Snjl 1099118611Snjl if (!MethodInfo) 1100118611Snjl { 1101151937Sjkim /* 1102151937Sjkim * Probably was an error in the method declaration, 1103151937Sjkim * no additional error here 1104151937Sjkim */ 1105167802Sjkim ACPI_WARNING ((AE_INFO, "%p, No parent method", Op)); 1106118611Snjl return (AE_ERROR); 1107118611Snjl } 1108118611Snjl 1109118611Snjl /* Child indicates a return value */ 1110118611Snjl 1111118611Snjl if ((Op->Asl.Child) && 1112118611Snjl (Op->Asl.Child->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG)) 1113118611Snjl { 1114118611Snjl MethodInfo->NumReturnWithValue++; 1115118611Snjl } 1116118611Snjl else 1117118611Snjl { 1118118611Snjl MethodInfo->NumReturnNoValue++; 1119118611Snjl } 1120118611Snjl break; 1121118611Snjl 1122118611Snjl 1123118611Snjl case PARSEOP_BREAK: 1124118611Snjl case PARSEOP_CONTINUE: 1125118611Snjl 1126118611Snjl Next = Op->Asl.Parent; 1127118611Snjl while (Next) 1128118611Snjl { 1129118611Snjl if (Next->Asl.ParseOpcode == PARSEOP_WHILE) 1130118611Snjl { 1131118611Snjl break; 1132118611Snjl } 1133118611Snjl Next = Next->Asl.Parent; 1134118611Snjl } 1135118611Snjl 1136118611Snjl if (!Next) 1137118611Snjl { 1138118611Snjl AslError (ASL_ERROR, ASL_MSG_NO_WHILE, Op, NULL); 1139118611Snjl } 1140118611Snjl break; 1141118611Snjl 1142118611Snjl 1143123315Snjl case PARSEOP_STALL: 1144123315Snjl 1145151937Sjkim /* We can range check if the argument is an integer */ 1146151937Sjkim 1147151937Sjkim if ((Op->Asl.Child->Asl.ParseOpcode == PARSEOP_INTEGER) && 1148151937Sjkim (Op->Asl.Child->Asl.Value.Integer > ACPI_UINT8_MAX)) 1149123315Snjl { 1150123315Snjl AslError (ASL_ERROR, ASL_MSG_INVALID_TIME, Op, NULL); 1151123315Snjl } 1152123315Snjl break; 1153123315Snjl 1154123315Snjl 1155118611Snjl case PARSEOP_DEVICE: 1156118611Snjl case PARSEOP_EVENT: 1157118611Snjl case PARSEOP_MUTEX: 1158118611Snjl case PARSEOP_OPERATIONREGION: 1159118611Snjl case PARSEOP_POWERRESOURCE: 1160118611Snjl case PARSEOP_PROCESSOR: 1161118611Snjl case PARSEOP_THERMALZONE: 1162118611Snjl 1163118611Snjl /* 1164118611Snjl * The first operand is a name to be created in the namespace. 1165118611Snjl * Check against the reserved list. 1166118611Snjl */ 1167118611Snjl i = AnCheckForReservedName (Op, Op->Asl.NameSeg); 1168118611Snjl if (i < ACPI_VALID_RESERVED_NAME_MAX) 1169118611Snjl { 1170118611Snjl AslError (ASL_ERROR, ASL_MSG_RESERVED_USE, Op, Op->Asl.ExternalName); 1171118611Snjl } 1172118611Snjl break; 1173118611Snjl 1174118611Snjl 1175118611Snjl case PARSEOP_NAME: 1176118611Snjl 1177118611Snjl i = AnCheckForReservedName (Op, Op->Asl.NameSeg); 1178118611Snjl if (i < ACPI_VALID_RESERVED_NAME_MAX) 1179118611Snjl { 1180118611Snjl if (ReservedMethods[i].NumArguments > 0) 1181118611Snjl { 1182118611Snjl /* 1183118611Snjl * This reserved name must be a control method because 1184118611Snjl * it must have arguments 1185118611Snjl */ 1186151937Sjkim AslError (ASL_ERROR, ASL_MSG_RESERVED_METHOD, Op, 1187151937Sjkim "with arguments"); 1188118611Snjl } 1189118611Snjl 1190151937Sjkim /* Typechecking for _HID */ 1191151937Sjkim 1192118611Snjl else if (!ACPI_STRCMP (METHOD_NAME__HID, ReservedMethods[i].Name)) 1193118611Snjl { 1194118611Snjl /* Examine the second operand to typecheck it */ 1195118611Snjl 1196118611Snjl Next = Op->Asl.Child->Asl.Next; 1197118611Snjl 1198118611Snjl if ((Next->Asl.ParseOpcode != PARSEOP_INTEGER) && 1199118611Snjl (Next->Asl.ParseOpcode != PARSEOP_STRING_LITERAL)) 1200118611Snjl { 1201118611Snjl /* _HID must be a string or an integer */ 1202118611Snjl 1203151937Sjkim AslError (ASL_ERROR, ASL_MSG_RESERVED_OPERAND_TYPE, Next, 1204151937Sjkim "String or Integer"); 1205118611Snjl } 1206118611Snjl 1207118611Snjl if (Next->Asl.ParseOpcode == PARSEOP_STRING_LITERAL) 1208118611Snjl { 1209118611Snjl /* 1210118611Snjl * _HID is a string, all characters must be alphanumeric. 1211118611Snjl * One of the things we want to catch here is the use of 1212118611Snjl * a leading asterisk in the string. 1213118611Snjl */ 1214118611Snjl for (i = 0; Next->Asl.Value.String[i]; i++) 1215118611Snjl { 1216118611Snjl if (!isalnum (Next->Asl.Value.String[i])) 1217118611Snjl { 1218151937Sjkim AslError (ASL_ERROR, ASL_MSG_ALPHANUMERIC_STRING, 1219151937Sjkim Next, Next->Asl.Value.String); 1220118611Snjl break; 1221118611Snjl } 1222118611Snjl } 1223118611Snjl } 1224118611Snjl } 1225118611Snjl } 1226118611Snjl break; 1227118611Snjl 1228118611Snjl 1229118611Snjl default: 1230118611Snjl break; 1231118611Snjl } 1232118611Snjl 1233118611Snjl return AE_OK; 1234118611Snjl} 1235118611Snjl 1236118611Snjl 1237118611Snjl/******************************************************************************* 1238118611Snjl * 1239118611Snjl * FUNCTION: AnLastStatementIsReturn 1240118611Snjl * 1241118611Snjl * PARAMETERS: Op - A method parse node 1242118611Snjl * 1243167802Sjkim * RETURN: TRUE if last statement is an ASL RETURN. False otherwise 1244118611Snjl * 1245118611Snjl * DESCRIPTION: Walk down the list of top level statements within a method 1246167802Sjkim * to find the last one. Check if that last statement is in 1247118611Snjl * fact a RETURN statement. 1248118611Snjl * 1249118611Snjl ******************************************************************************/ 1250118611Snjl 1251151937Sjkimstatic BOOLEAN 1252118611SnjlAnLastStatementIsReturn ( 1253118611Snjl ACPI_PARSE_OBJECT *Op) 1254118611Snjl{ 1255118611Snjl ACPI_PARSE_OBJECT *Next; 1256118611Snjl 1257118611Snjl 1258118611Snjl /* 1259118611Snjl * Check if last statement is a return 1260118611Snjl */ 1261118611Snjl Next = ASL_GET_CHILD_NODE (Op); 1262118611Snjl while (Next) 1263118611Snjl { 1264118611Snjl if ((!Next->Asl.Next) && 1265118611Snjl (Next->Asl.ParseOpcode == PARSEOP_RETURN)) 1266118611Snjl { 1267118611Snjl return TRUE; 1268118611Snjl } 1269118611Snjl 1270118611Snjl Next = ASL_GET_PEER_NODE (Next); 1271118611Snjl } 1272118611Snjl 1273118611Snjl return FALSE; 1274118611Snjl} 1275118611Snjl 1276118611Snjl 1277118611Snjl/******************************************************************************* 1278118611Snjl * 1279118611Snjl * FUNCTION: AnMethodAnalysisWalkEnd 1280118611Snjl * 1281118611Snjl * PARAMETERS: ASL_WALK_CALLBACK 1282118611Snjl * 1283118611Snjl * RETURN: Status 1284118611Snjl * 1285167802Sjkim * DESCRIPTION: Ascending callback for analysis walk. Complete method 1286118611Snjl * return analysis. 1287118611Snjl * 1288118611Snjl ******************************************************************************/ 1289118611Snjl 1290118611SnjlACPI_STATUS 1291118611SnjlAnMethodAnalysisWalkEnd ( 1292118611Snjl ACPI_PARSE_OBJECT *Op, 1293118611Snjl UINT32 Level, 1294118611Snjl void *Context) 1295118611Snjl{ 1296118611Snjl ASL_ANALYSIS_WALK_INFO *WalkInfo = (ASL_ANALYSIS_WALK_INFO *) Context; 1297118611Snjl ASL_METHOD_INFO *MethodInfo = WalkInfo->MethodStack; 1298118611Snjl 1299118611Snjl 1300118611Snjl switch (Op->Asl.ParseOpcode) 1301118611Snjl { 1302118611Snjl case PARSEOP_METHOD: 1303118611Snjl case PARSEOP_RETURN: 1304118611Snjl if (!MethodInfo) 1305118611Snjl { 1306118611Snjl printf ("No method info for method! [%s]\n", Op->Asl.Namepath); 1307151937Sjkim AslError (ASL_ERROR, ASL_MSG_COMPILER_INTERNAL, Op, 1308151937Sjkim "No method info for this method"); 1309118611Snjl CmCleanupAndExit (); 1310118611Snjl return (AE_AML_INTERNAL); 1311118611Snjl } 1312118611Snjl break; 1313118611Snjl 1314118611Snjl default: 1315118611Snjl break; 1316118611Snjl } 1317118611Snjl 1318118611Snjl switch (Op->Asl.ParseOpcode) 1319118611Snjl { 1320118611Snjl case PARSEOP_METHOD: 1321118611Snjl 1322118611Snjl WalkInfo->MethodStack = MethodInfo->Next; 1323118611Snjl 1324118611Snjl /* 1325118611Snjl * Check if there is no return statement at the end of the 1326118611Snjl * method AND we can actually get there -- i.e., the execution 1327118611Snjl * of the method can possibly terminate without a return statement. 1328118611Snjl */ 1329118611Snjl if ((!AnLastStatementIsReturn (Op)) && 1330118611Snjl (!(Op->Asl.CompileFlags & NODE_HAS_NO_EXIT))) 1331118611Snjl { 1332118611Snjl /* 1333118611Snjl * No return statement, and execution can possibly exit 1334167802Sjkim * via this path. This is equivalent to Return () 1335118611Snjl */ 1336118611Snjl MethodInfo->NumReturnNoValue++; 1337118611Snjl } 1338118611Snjl 1339118611Snjl /* 1340118611Snjl * Check for case where some return statements have a return value 1341167802Sjkim * and some do not. Exit without a return statement is a return with 1342118611Snjl * no value 1343118611Snjl */ 1344118611Snjl if (MethodInfo->NumReturnNoValue && 1345118611Snjl MethodInfo->NumReturnWithValue) 1346118611Snjl { 1347151937Sjkim AslError (ASL_WARNING, ASL_MSG_RETURN_TYPES, Op, 1348151937Sjkim Op->Asl.ExternalName); 1349118611Snjl } 1350118611Snjl 1351118611Snjl /* 1352118611Snjl * If there are any RETURN() statements with no value, or there is a 1353118611Snjl * control path that allows the method to exit without a return value, 1354167802Sjkim * we mark the method as a method that does not return a value. This 1355118611Snjl * knowledge can be used to check method invocations that expect a 1356118611Snjl * returned value. 1357118611Snjl */ 1358118611Snjl if (MethodInfo->NumReturnNoValue) 1359118611Snjl { 1360118611Snjl if (MethodInfo->NumReturnWithValue) 1361118611Snjl { 1362118611Snjl Op->Asl.CompileFlags |= NODE_METHOD_SOME_NO_RETVAL; 1363118611Snjl } 1364118611Snjl else 1365118611Snjl { 1366118611Snjl Op->Asl.CompileFlags |= NODE_METHOD_NO_RETVAL; 1367118611Snjl } 1368118611Snjl } 1369118611Snjl 1370118611Snjl /* 1371118611Snjl * Check predefined method names for correct return behavior 1372118611Snjl * and correct number of arguments 1373118611Snjl */ 1374118611Snjl AnCheckForReservedMethod (Op, MethodInfo); 1375167802Sjkim ACPI_FREE (MethodInfo); 1376118611Snjl break; 1377118611Snjl 1378118611Snjl 1379118611Snjl case PARSEOP_RETURN: 1380118611Snjl 1381118611Snjl /* 1382118611Snjl * The parent block does not "exit" and continue execution -- the 1383118611Snjl * method is terminated here with the Return() statement. 1384118611Snjl */ 1385118611Snjl Op->Asl.Parent->Asl.CompileFlags |= NODE_HAS_NO_EXIT; 1386118611Snjl 1387151937Sjkim /* Used in the "typing" pass later */ 1388151937Sjkim 1389151937Sjkim Op->Asl.ParentMethod = MethodInfo->Op; 1390151937Sjkim 1391118611Snjl /* 1392118611Snjl * If there is a peer node after the return statement, then this 1393151937Sjkim * node is unreachable code -- i.e., it won't be executed because of 1394167802Sjkim * the preceeding Return() statement. 1395118611Snjl */ 1396118611Snjl if (Op->Asl.Next) 1397118611Snjl { 1398118611Snjl AslError (ASL_WARNING, ASL_MSG_UNREACHABLE_CODE, Op->Asl.Next, NULL); 1399118611Snjl } 1400118611Snjl break; 1401118611Snjl 1402118611Snjl 1403118611Snjl case PARSEOP_IF: 1404118611Snjl 1405118611Snjl if ((Op->Asl.CompileFlags & NODE_HAS_NO_EXIT) && 1406118611Snjl (Op->Asl.Next) && 1407118611Snjl (Op->Asl.Next->Asl.ParseOpcode == PARSEOP_ELSE)) 1408118611Snjl { 1409118611Snjl /* 1410167802Sjkim * This IF has a corresponding ELSE. The IF block has no exit, 1411118611Snjl * (it contains an unconditional Return) 1412118611Snjl * mark the ELSE block to remember this fact. 1413118611Snjl */ 1414118611Snjl Op->Asl.Next->Asl.CompileFlags |= NODE_IF_HAS_NO_EXIT; 1415118611Snjl } 1416118611Snjl break; 1417118611Snjl 1418118611Snjl 1419118611Snjl case PARSEOP_ELSE: 1420118611Snjl 1421118611Snjl if ((Op->Asl.CompileFlags & NODE_HAS_NO_EXIT) && 1422118611Snjl (Op->Asl.CompileFlags & NODE_IF_HAS_NO_EXIT)) 1423118611Snjl { 1424118611Snjl /* 1425118611Snjl * This ELSE block has no exit and the corresponding IF block 1426167802Sjkim * has no exit either. Therefore, the parent node has no exit. 1427118611Snjl */ 1428118611Snjl Op->Asl.Parent->Asl.CompileFlags |= NODE_HAS_NO_EXIT; 1429118611Snjl } 1430118611Snjl break; 1431118611Snjl 1432118611Snjl 1433118611Snjl default: 1434118611Snjl 1435118611Snjl if ((Op->Asl.CompileFlags & NODE_HAS_NO_EXIT) && 1436118611Snjl (Op->Asl.Parent)) 1437118611Snjl { 1438118611Snjl /* If this node has no exit, then the parent has no exit either */ 1439118611Snjl 1440118611Snjl Op->Asl.Parent->Asl.CompileFlags |= NODE_HAS_NO_EXIT; 1441118611Snjl } 1442118611Snjl break; 1443118611Snjl } 1444118611Snjl 1445118611Snjl return AE_OK; 1446118611Snjl} 1447118611Snjl 1448118611Snjl 1449118611Snjl/******************************************************************************* 1450118611Snjl * 1451118611Snjl * FUNCTION: AnMethodTypingWalkBegin 1452118611Snjl * 1453118611Snjl * PARAMETERS: ASL_WALK_CALLBACK 1454118611Snjl * 1455118611Snjl * RETURN: Status 1456118611Snjl * 1457118611Snjl * DESCRIPTION: Descending callback for the typing walk. 1458118611Snjl * 1459118611Snjl ******************************************************************************/ 1460118611Snjl 1461118611SnjlACPI_STATUS 1462118611SnjlAnMethodTypingWalkBegin ( 1463118611Snjl ACPI_PARSE_OBJECT *Op, 1464118611Snjl UINT32 Level, 1465118611Snjl void *Context) 1466118611Snjl{ 1467118611Snjl 1468118611Snjl return AE_OK; 1469118611Snjl} 1470118611Snjl 1471118611Snjl 1472118611Snjl/******************************************************************************* 1473118611Snjl * 1474118611Snjl * FUNCTION: AnMethodTypingWalkEnd 1475118611Snjl * 1476118611Snjl * PARAMETERS: ASL_WALK_CALLBACK 1477118611Snjl * 1478118611Snjl * RETURN: Status 1479118611Snjl * 1480167802Sjkim * DESCRIPTION: Ascending callback for typing walk. Complete the method 1481167802Sjkim * return analysis. Check methods for: 1482118611Snjl * 1) Initialized local variables 1483118611Snjl * 2) Valid arguments 1484118611Snjl * 3) Return types 1485118611Snjl * 1486118611Snjl ******************************************************************************/ 1487118611Snjl 1488118611SnjlACPI_STATUS 1489118611SnjlAnMethodTypingWalkEnd ( 1490118611Snjl ACPI_PARSE_OBJECT *Op, 1491118611Snjl UINT32 Level, 1492118611Snjl void *Context) 1493118611Snjl{ 1494118611Snjl UINT32 ThisNodeBtype; 1495118611Snjl 1496118611Snjl 1497118611Snjl switch (Op->Asl.ParseOpcode) 1498118611Snjl { 1499118611Snjl case PARSEOP_METHOD: 1500118611Snjl 1501118611Snjl Op->Asl.CompileFlags |= NODE_METHOD_TYPED; 1502118611Snjl break; 1503118611Snjl 1504118611Snjl case PARSEOP_RETURN: 1505118611Snjl 1506118611Snjl if ((Op->Asl.Child) && 1507118611Snjl (Op->Asl.Child->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG)) 1508118611Snjl { 1509118611Snjl ThisNodeBtype = AnGetBtype (Op->Asl.Child); 1510118611Snjl 1511118611Snjl if ((Op->Asl.Child->Asl.ParseOpcode == PARSEOP_METHODCALL) && 1512118611Snjl (ThisNodeBtype == (ACPI_UINT32_MAX -1))) 1513118611Snjl { 1514118611Snjl /* 1515167802Sjkim * The called method is untyped at this time (typically a 1516167802Sjkim * forward reference). 1517167802Sjkim * 1518167802Sjkim * Check for a recursive method call first. 1519118611Snjl */ 1520167802Sjkim if (Op->Asl.ParentMethod != Op->Asl.Child->Asl.Node->Op) 1521167802Sjkim { 1522167802Sjkim /* We must type the method here */ 1523118611Snjl 1524167802Sjkim TrWalkParseTree (Op->Asl.Child->Asl.Node->Op, 1525167802Sjkim ASL_WALK_VISIT_TWICE, AnMethodTypingWalkBegin, 1526167802Sjkim AnMethodTypingWalkEnd, NULL); 1527167802Sjkim 1528167802Sjkim ThisNodeBtype = AnGetBtype (Op->Asl.Child); 1529167802Sjkim } 1530118611Snjl } 1531118611Snjl 1532167802Sjkim /* Returns a value, save the value type */ 1533118611Snjl 1534118611Snjl if (Op->Asl.ParentMethod) 1535118611Snjl { 1536118611Snjl Op->Asl.ParentMethod->Asl.AcpiBtype |= ThisNodeBtype; 1537118611Snjl } 1538118611Snjl } 1539118611Snjl break; 1540118611Snjl 1541118611Snjl default: 1542118611Snjl break; 1543118611Snjl } 1544118611Snjl 1545118611Snjl return AE_OK; 1546118611Snjl} 1547118611Snjl 1548118611Snjl 1549118611Snjl/******************************************************************************* 1550118611Snjl * 1551118611Snjl * FUNCTION: AnCheckMethodReturnValue 1552118611Snjl * 1553118611Snjl * PARAMETERS: Op - Parent 1554118611Snjl * OpInfo - Parent info 1555118611Snjl * ArgOp - Method invocation op 1556118611Snjl * RequiredBtypes - What caller requires 1557118611Snjl * ThisNodeBtype - What this node returns (if anything) 1558118611Snjl * 1559118611Snjl * RETURN: None 1560118611Snjl * 1561118611Snjl * DESCRIPTION: Check a method invocation for 1) A return value and if it does 1562118611Snjl * in fact return a value, 2) check the type of the return value. 1563118611Snjl * 1564118611Snjl ******************************************************************************/ 1565118611Snjl 1566151937Sjkimstatic void 1567118611SnjlAnCheckMethodReturnValue ( 1568118611Snjl ACPI_PARSE_OBJECT *Op, 1569118611Snjl const ACPI_OPCODE_INFO *OpInfo, 1570118611Snjl ACPI_PARSE_OBJECT *ArgOp, 1571118611Snjl UINT32 RequiredBtypes, 1572118611Snjl UINT32 ThisNodeBtype) 1573118611Snjl{ 1574118611Snjl ACPI_PARSE_OBJECT *OwningOp; 1575118611Snjl ACPI_NAMESPACE_NODE *Node; 1576118611Snjl 1577118611Snjl 1578118611Snjl Node = ArgOp->Asl.Node; 1579118611Snjl 1580118611Snjl 1581118611Snjl /* Examine the parent op of this method */ 1582118611Snjl 1583151937Sjkim OwningOp = Node->Op; 1584118611Snjl if (OwningOp->Asl.CompileFlags & NODE_METHOD_NO_RETVAL) 1585118611Snjl { 1586151937Sjkim /* Method NEVER returns a value */ 1587151937Sjkim 1588118611Snjl AslError (ASL_ERROR, ASL_MSG_NO_RETVAL, Op, Op->Asl.ExternalName); 1589118611Snjl } 1590118611Snjl else if (OwningOp->Asl.CompileFlags & NODE_METHOD_SOME_NO_RETVAL) 1591118611Snjl { 1592151937Sjkim /* Method SOMETIMES returns a value, SOMETIMES not */ 1593151937Sjkim 1594118611Snjl AslError (ASL_WARNING, ASL_MSG_SOME_NO_RETVAL, Op, Op->Asl.ExternalName); 1595118611Snjl } 1596118611Snjl else if (!(ThisNodeBtype & RequiredBtypes)) 1597118611Snjl { 1598151937Sjkim /* Method returns a value, but the type is wrong */ 1599151937Sjkim 1600118611Snjl AnFormatBtype (StringBuffer, ThisNodeBtype); 1601118611Snjl AnFormatBtype (StringBuffer2, RequiredBtypes); 1602118611Snjl 1603118611Snjl 1604118611Snjl /* 1605118611Snjl * The case where the method does not return any value at all 1606118611Snjl * was already handled in the namespace cross reference 1607118611Snjl * -- Only issue an error if the method in fact returns a value, 1608118611Snjl * but it is of the wrong type 1609118611Snjl */ 1610118611Snjl if (ThisNodeBtype != 0) 1611118611Snjl { 1612151937Sjkim sprintf (MsgBuffer, 1613151937Sjkim "Method returns [%s], %s operator requires [%s]", 1614151937Sjkim StringBuffer, OpInfo->Name, StringBuffer2); 1615118611Snjl 1616118611Snjl AslError (ASL_ERROR, ASL_MSG_INVALID_TYPE, ArgOp, MsgBuffer); 1617118611Snjl } 1618118611Snjl } 1619118611Snjl} 1620118611Snjl 1621118611Snjl 1622118611Snjl/******************************************************************************* 1623118611Snjl * 1624118611Snjl * FUNCTION: AnOperandTypecheckWalkBegin 1625118611Snjl * 1626118611Snjl * PARAMETERS: ASL_WALK_CALLBACK 1627118611Snjl * 1628118611Snjl * RETURN: Status 1629118611Snjl * 1630167802Sjkim * DESCRIPTION: Descending callback for the analysis walk. Check methods for: 1631118611Snjl * 1) Initialized local variables 1632118611Snjl * 2) Valid arguments 1633118611Snjl * 3) Return types 1634118611Snjl * 1635118611Snjl ******************************************************************************/ 1636118611Snjl 1637118611SnjlACPI_STATUS 1638118611SnjlAnOperandTypecheckWalkBegin ( 1639118611Snjl ACPI_PARSE_OBJECT *Op, 1640118611Snjl UINT32 Level, 1641118611Snjl void *Context) 1642118611Snjl{ 1643118611Snjl 1644118611Snjl return AE_OK; 1645118611Snjl} 1646118611Snjl 1647118611Snjl 1648118611Snjl/******************************************************************************* 1649118611Snjl * 1650118611Snjl * FUNCTION: AnOperandTypecheckWalkEnd 1651118611Snjl * 1652118611Snjl * PARAMETERS: ASL_WALK_CALLBACK 1653118611Snjl * 1654118611Snjl * RETURN: Status 1655118611Snjl * 1656167802Sjkim * DESCRIPTION: Ascending callback for analysis walk. Complete method 1657118611Snjl * return analysis. 1658118611Snjl * 1659118611Snjl ******************************************************************************/ 1660118611Snjl 1661118611SnjlACPI_STATUS 1662118611SnjlAnOperandTypecheckWalkEnd ( 1663118611Snjl ACPI_PARSE_OBJECT *Op, 1664118611Snjl UINT32 Level, 1665118611Snjl void *Context) 1666118611Snjl{ 1667118611Snjl const ACPI_OPCODE_INFO *OpInfo; 1668118611Snjl UINT32 RuntimeArgTypes; 1669118611Snjl UINT32 RuntimeArgTypes2; 1670118611Snjl UINT32 RequiredBtypes; 1671118611Snjl UINT32 ThisNodeBtype; 1672118611Snjl UINT32 CommonBtypes; 1673118611Snjl UINT32 OpcodeClass; 1674118611Snjl ACPI_PARSE_OBJECT *ArgOp; 1675118611Snjl UINT32 ArgType; 1676118611Snjl 1677118611Snjl 1678118611Snjl switch (Op->Asl.AmlOpcode) 1679118611Snjl { 1680118611Snjl case AML_RAW_DATA_BYTE: 1681118611Snjl case AML_RAW_DATA_WORD: 1682118611Snjl case AML_RAW_DATA_DWORD: 1683118611Snjl case AML_RAW_DATA_QWORD: 1684118611Snjl case AML_RAW_DATA_BUFFER: 1685118611Snjl case AML_RAW_DATA_CHAIN: 1686118611Snjl case AML_PACKAGE_LENGTH: 1687118611Snjl case AML_UNASSIGNED_OPCODE: 1688118611Snjl case AML_DEFAULT_ARG_OP: 1689118611Snjl 1690118611Snjl /* Ignore the internal (compiler-only) AML opcodes */ 1691118611Snjl 1692118611Snjl return (AE_OK); 1693118611Snjl 1694118611Snjl default: 1695118611Snjl break; 1696118611Snjl } 1697118611Snjl 1698118611Snjl OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode); 1699118611Snjl if (!OpInfo) 1700118611Snjl { 1701118611Snjl return (AE_OK); 1702118611Snjl } 1703118611Snjl 1704118611Snjl ArgOp = Op->Asl.Child; 1705118611Snjl RuntimeArgTypes = OpInfo->RuntimeArgs; 1706118611Snjl OpcodeClass = OpInfo->Class; 1707118611Snjl 1708118611Snjl 1709118611Snjl /* 1710118611Snjl * Special case for control opcodes IF/RETURN/WHILE since they 1711118611Snjl * have no runtime arg list (at this time) 1712118611Snjl */ 1713118611Snjl switch (Op->Asl.AmlOpcode) 1714118611Snjl { 1715118611Snjl case AML_IF_OP: 1716118611Snjl case AML_WHILE_OP: 1717118611Snjl case AML_RETURN_OP: 1718118611Snjl 1719118611Snjl if (ArgOp->Asl.ParseOpcode == PARSEOP_METHODCALL) 1720118611Snjl { 1721167802Sjkim /* Check for an internal method */ 1722167802Sjkim 1723167802Sjkim if (AnIsInternalMethod (ArgOp)) 1724151937Sjkim { 1725151937Sjkim return (AE_OK); 1726151937Sjkim } 1727151937Sjkim 1728118611Snjl /* The lone arg is a method call, check it */ 1729118611Snjl 1730118611Snjl RequiredBtypes = AnMapArgTypeToBtype (ARGI_INTEGER); 1731118611Snjl if (Op->Asl.AmlOpcode == AML_RETURN_OP) 1732118611Snjl { 1733118611Snjl RequiredBtypes = 0xFFFFFFFF; 1734118611Snjl } 1735118611Snjl 1736118611Snjl ThisNodeBtype = AnGetBtype (ArgOp); 1737118611Snjl if (ThisNodeBtype == ACPI_UINT32_MAX) 1738118611Snjl { 1739118611Snjl return (AE_OK); 1740118611Snjl } 1741151937Sjkim AnCheckMethodReturnValue (Op, OpInfo, ArgOp, 1742151937Sjkim RequiredBtypes, ThisNodeBtype); 1743118611Snjl } 1744118611Snjl return (AE_OK); 1745118611Snjl 1746118611Snjl default: 1747118611Snjl break; 1748118611Snjl } 1749118611Snjl 1750118611Snjl /* Ignore the non-executable opcodes */ 1751118611Snjl 1752118611Snjl if (RuntimeArgTypes == ARGI_INVALID_OPCODE) 1753118611Snjl { 1754118611Snjl return (AE_OK); 1755118611Snjl } 1756118611Snjl 1757118611Snjl switch (OpcodeClass) 1758118611Snjl { 1759118611Snjl case AML_CLASS_EXECUTE: 1760118611Snjl case AML_CLASS_CREATE: 1761118611Snjl case AML_CLASS_CONTROL: 1762118611Snjl case AML_CLASS_RETURN_VALUE: 1763118611Snjl 1764118611Snjl /* TBD: Change class or fix typechecking for these */ 1765118611Snjl 1766118611Snjl if ((Op->Asl.AmlOpcode == AML_BUFFER_OP) || 1767118611Snjl (Op->Asl.AmlOpcode == AML_PACKAGE_OP) || 1768118611Snjl (Op->Asl.AmlOpcode == AML_VAR_PACKAGE_OP)) 1769118611Snjl { 1770118611Snjl break; 1771118611Snjl } 1772118611Snjl 1773118611Snjl /* Reverse the runtime argument list */ 1774118611Snjl 1775118611Snjl RuntimeArgTypes2 = 0; 1776118611Snjl while ((ArgType = GET_CURRENT_ARG_TYPE (RuntimeArgTypes))) 1777118611Snjl { 1778118611Snjl RuntimeArgTypes2 <<= ARG_TYPE_WIDTH; 1779118611Snjl RuntimeArgTypes2 |= ArgType; 1780118611Snjl INCREMENT_ARG_LIST (RuntimeArgTypes); 1781118611Snjl } 1782118611Snjl 1783118611Snjl while ((ArgType = GET_CURRENT_ARG_TYPE (RuntimeArgTypes2))) 1784118611Snjl { 1785118611Snjl RequiredBtypes = AnMapArgTypeToBtype (ArgType); 1786118611Snjl 1787118611Snjl ThisNodeBtype = AnGetBtype (ArgOp); 1788118611Snjl if (ThisNodeBtype == ACPI_UINT32_MAX) 1789118611Snjl { 1790118611Snjl goto NextArgument; 1791118611Snjl } 1792118611Snjl 1793118611Snjl /* Examine the arg based on the required type of the arg */ 1794118611Snjl 1795118611Snjl switch (ArgType) 1796118611Snjl { 1797118611Snjl case ARGI_TARGETREF: 1798118611Snjl 1799118611Snjl if (ArgOp->Asl.ParseOpcode == PARSEOP_ZERO) 1800118611Snjl { 1801118611Snjl /* ZERO is the placeholder for "don't store result" */ 1802118611Snjl 1803118611Snjl ThisNodeBtype = RequiredBtypes; 1804118611Snjl break; 1805118611Snjl } 1806118611Snjl 1807118611Snjl if (ArgOp->Asl.ParseOpcode == PARSEOP_INTEGER) 1808118611Snjl { 1809118611Snjl /* 1810118611Snjl * This is the case where an original reference to a resource 1811118611Snjl * descriptor field has been replaced by an (Integer) offset. 1812118611Snjl * These named fields are supported at compile-time only; 1813118611Snjl * the names are not passed to the interpreter (via the AML). 1814118611Snjl */ 1815118611Snjl if ((ArgOp->Asl.Node->Type == ACPI_TYPE_LOCAL_RESOURCE_FIELD) || 1816118611Snjl (ArgOp->Asl.Node->Type == ACPI_TYPE_LOCAL_RESOURCE)) 1817118611Snjl { 1818118611Snjl AslError (ASL_ERROR, ASL_MSG_RESOURCE_FIELD, ArgOp, NULL); 1819118611Snjl } 1820118611Snjl else 1821118611Snjl { 1822118611Snjl AslError (ASL_ERROR, ASL_MSG_INVALID_TYPE, ArgOp, NULL); 1823118611Snjl } 1824118611Snjl break; 1825118611Snjl } 1826118611Snjl 1827118611Snjl if ((ArgOp->Asl.ParseOpcode == PARSEOP_METHODCALL) || 1828118611Snjl (ArgOp->Asl.ParseOpcode == PARSEOP_DEREFOF)) 1829118611Snjl { 1830118611Snjl break; 1831118611Snjl } 1832118611Snjl 1833118611Snjl ThisNodeBtype = RequiredBtypes; 1834118611Snjl break; 1835118611Snjl 1836118611Snjl 1837118611Snjl case ARGI_REFERENCE: /* References */ 1838118611Snjl case ARGI_INTEGER_REF: 1839118611Snjl case ARGI_OBJECT_REF: 1840118611Snjl case ARGI_DEVICE_REF: 1841118611Snjl 1842118611Snjl switch (ArgOp->Asl.ParseOpcode) 1843118611Snjl { 1844118611Snjl case PARSEOP_LOCAL0: 1845118611Snjl case PARSEOP_LOCAL1: 1846118611Snjl case PARSEOP_LOCAL2: 1847118611Snjl case PARSEOP_LOCAL3: 1848118611Snjl case PARSEOP_LOCAL4: 1849118611Snjl case PARSEOP_LOCAL5: 1850118611Snjl case PARSEOP_LOCAL6: 1851118611Snjl case PARSEOP_LOCAL7: 1852118611Snjl 1853118611Snjl /* TBD: implement analysis of current value (type) of the local */ 1854118611Snjl /* For now, just treat any local as a typematch */ 1855118611Snjl 1856118611Snjl /*ThisNodeBtype = RequiredBtypes;*/ 1857118611Snjl break; 1858118611Snjl 1859118611Snjl case PARSEOP_ARG0: 1860118611Snjl case PARSEOP_ARG1: 1861118611Snjl case PARSEOP_ARG2: 1862118611Snjl case PARSEOP_ARG3: 1863118611Snjl case PARSEOP_ARG4: 1864118611Snjl case PARSEOP_ARG5: 1865118611Snjl case PARSEOP_ARG6: 1866118611Snjl 1867118611Snjl /* Hard to analyze argument types, sow we won't */ 1868118611Snjl /* For now, just treat any arg as a typematch */ 1869118611Snjl 1870118611Snjl /* ThisNodeBtype = RequiredBtypes; */ 1871118611Snjl break; 1872118611Snjl 1873118611Snjl case PARSEOP_DEBUG: 1874118611Snjl break; 1875118611Snjl 1876118611Snjl case PARSEOP_REFOF: 1877118611Snjl case PARSEOP_INDEX: 1878118611Snjl default: 1879118611Snjl break; 1880118611Snjl 1881118611Snjl } 1882118611Snjl break; 1883118611Snjl 1884118611Snjl case ARGI_INTEGER: 1885118611Snjl default: 1886118611Snjl break; 1887118611Snjl } 1888118611Snjl 1889118611Snjl 1890118611Snjl CommonBtypes = ThisNodeBtype & RequiredBtypes; 1891118611Snjl 1892118611Snjl if (ArgOp->Asl.ParseOpcode == PARSEOP_METHODCALL) 1893118611Snjl { 1894167802Sjkim if (AnIsInternalMethod (ArgOp)) 1895167802Sjkim { 1896167802Sjkim return (AE_OK); 1897167802Sjkim } 1898167802Sjkim 1899118611Snjl /* Check a method call for a valid return value */ 1900118611Snjl 1901151937Sjkim AnCheckMethodReturnValue (Op, OpInfo, ArgOp, 1902151937Sjkim RequiredBtypes, ThisNodeBtype); 1903118611Snjl } 1904118611Snjl 1905118611Snjl /* 1906118611Snjl * Now check if the actual type(s) match at least one 1907118611Snjl * bit to the required type 1908118611Snjl */ 1909118611Snjl else if (!CommonBtypes) 1910118611Snjl { 1911118611Snjl /* No match -- this is a type mismatch error */ 1912118611Snjl 1913118611Snjl AnFormatBtype (StringBuffer, ThisNodeBtype); 1914118611Snjl AnFormatBtype (StringBuffer2, RequiredBtypes); 1915118611Snjl 1916118611Snjl sprintf (MsgBuffer, "[%s] found, %s operator requires [%s]", 1917118611Snjl StringBuffer, OpInfo->Name, StringBuffer2); 1918118611Snjl 1919118611Snjl AslError (ASL_ERROR, ASL_MSG_INVALID_TYPE, ArgOp, MsgBuffer); 1920118611Snjl } 1921118611Snjl 1922118611Snjl NextArgument: 1923118611Snjl ArgOp = ArgOp->Asl.Next; 1924118611Snjl INCREMENT_ARG_LIST (RuntimeArgTypes2); 1925118611Snjl } 1926118611Snjl break; 1927118611Snjl 1928118611Snjl default: 1929118611Snjl break; 1930118611Snjl } 1931118611Snjl 1932118611Snjl return (AE_OK); 1933118611Snjl} 1934118611Snjl 1935118611Snjl 1936118611Snjl/******************************************************************************* 1937118611Snjl * 1938167802Sjkim * FUNCTION: AnIsResultUsed 1939167802Sjkim * 1940167802Sjkim * PARAMETERS: Op - Parent op for the operator 1941167802Sjkim * 1942167802Sjkim * RETURN: TRUE if result from this operation is actually consumed 1943167802Sjkim * 1944167802Sjkim * DESCRIPTION: Determine if the function result value from an operator is 1945167802Sjkim * used. 1946167802Sjkim * 1947167802Sjkim ******************************************************************************/ 1948167802Sjkim 1949167802SjkimBOOLEAN 1950167802SjkimAnIsResultUsed ( 1951167802Sjkim ACPI_PARSE_OBJECT *Op) 1952167802Sjkim{ 1953167802Sjkim ACPI_PARSE_OBJECT *Parent; 1954167802Sjkim 1955167802Sjkim 1956167802Sjkim switch (Op->Asl.ParseOpcode) 1957167802Sjkim { 1958167802Sjkim case PARSEOP_INCREMENT: 1959167802Sjkim case PARSEOP_DECREMENT: 1960167802Sjkim 1961167802Sjkim /* These are standalone operators, no return value */ 1962167802Sjkim 1963167802Sjkim return (TRUE); 1964167802Sjkim 1965167802Sjkim default: 1966167802Sjkim break; 1967167802Sjkim } 1968167802Sjkim 1969167802Sjkim /* Examine parent to determine if the return value is used */ 1970167802Sjkim 1971167802Sjkim Parent = Op->Asl.Parent; 1972167802Sjkim switch (Parent->Asl.ParseOpcode) 1973167802Sjkim { 1974167802Sjkim /* If/While - check if the operator is the predicate */ 1975167802Sjkim 1976167802Sjkim case PARSEOP_IF: 1977167802Sjkim case PARSEOP_WHILE: 1978167802Sjkim 1979167802Sjkim /* First child is the predicate */ 1980167802Sjkim 1981167802Sjkim if (Parent->Asl.Child == Op) 1982167802Sjkim { 1983167802Sjkim return (TRUE); 1984167802Sjkim } 1985167802Sjkim return (FALSE); 1986167802Sjkim 1987167802Sjkim /* Not used if one of these is the parent */ 1988167802Sjkim 1989167802Sjkim case PARSEOP_METHOD: 1990167802Sjkim case PARSEOP_DEFINITIONBLOCK: 1991167802Sjkim case PARSEOP_ELSE: 1992167802Sjkim 1993167802Sjkim return (FALSE); 1994167802Sjkim 1995167802Sjkim default: 1996167802Sjkim /* Any other type of parent means that the result is used */ 1997167802Sjkim 1998167802Sjkim return (TRUE); 1999167802Sjkim } 2000167802Sjkim} 2001167802Sjkim 2002167802Sjkim 2003167802Sjkim/******************************************************************************* 2004167802Sjkim * 2005118611Snjl * FUNCTION: AnOtherSemanticAnalysisWalkBegin 2006118611Snjl * 2007118611Snjl * PARAMETERS: ASL_WALK_CALLBACK 2008118611Snjl * 2009118611Snjl * RETURN: Status 2010118611Snjl * 2011167802Sjkim * DESCRIPTION: Descending callback for the analysis walk. Checks for 2012167802Sjkim * miscellaneous issues in the code. 2013118611Snjl * 2014118611Snjl ******************************************************************************/ 2015118611Snjl 2016118611SnjlACPI_STATUS 2017118611SnjlAnOtherSemanticAnalysisWalkBegin ( 2018118611Snjl ACPI_PARSE_OBJECT *Op, 2019118611Snjl UINT32 Level, 2020118611Snjl void *Context) 2021118611Snjl{ 2022167802Sjkim ACPI_PARSE_OBJECT *ArgNode; 2023167802Sjkim ACPI_PARSE_OBJECT *PrevArgNode = NULL; 2024167802Sjkim const ACPI_OPCODE_INFO *OpInfo; 2025118611Snjl 2026167802Sjkim 2027167802Sjkim OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode); 2028167802Sjkim 2029167802Sjkim /* 2030167802Sjkim * Determine if an execution class operator actually does something by 2031167802Sjkim * checking if it has a target and/or the function return value is used. 2032167802Sjkim * (Target is optional, so a standalone statement can actually do nothing.) 2033167802Sjkim */ 2034167802Sjkim if ((OpInfo->Class == AML_CLASS_EXECUTE) && 2035167802Sjkim (OpInfo->Flags & AML_HAS_RETVAL) && 2036167802Sjkim (!AnIsResultUsed (Op))) 2037167802Sjkim { 2038167802Sjkim if (OpInfo->Flags & AML_HAS_TARGET) 2039167802Sjkim { 2040167802Sjkim /* 2041167802Sjkim * Find the target node, it is always the last child. If the traget 2042167802Sjkim * is not specified in the ASL, a default node of type Zero was 2043167802Sjkim * created by the parser. 2044167802Sjkim */ 2045167802Sjkim ArgNode = Op->Asl.Child; 2046167802Sjkim while (ArgNode->Asl.Next) 2047167802Sjkim { 2048167802Sjkim PrevArgNode = ArgNode; 2049167802Sjkim ArgNode = ArgNode->Asl.Next; 2050167802Sjkim } 2051167802Sjkim 2052167802Sjkim /* Divide() is the only weird case, it has two targets */ 2053167802Sjkim 2054167802Sjkim if (Op->Asl.AmlOpcode == AML_DIVIDE_OP) 2055167802Sjkim { 2056167802Sjkim if ((ArgNode->Asl.ParseOpcode == PARSEOP_ZERO) && 2057167802Sjkim (PrevArgNode->Asl.ParseOpcode == PARSEOP_ZERO)) 2058167802Sjkim { 2059167802Sjkim AslError (ASL_WARNING, ASL_MSG_RESULT_NOT_USED, Op, Op->Asl.ExternalName); 2060167802Sjkim } 2061167802Sjkim } 2062167802Sjkim else if (ArgNode->Asl.ParseOpcode == PARSEOP_ZERO) 2063167802Sjkim { 2064167802Sjkim AslError (ASL_WARNING, ASL_MSG_RESULT_NOT_USED, Op, Op->Asl.ExternalName); 2065167802Sjkim } 2066167802Sjkim } 2067167802Sjkim else 2068167802Sjkim { 2069167802Sjkim /* 2070167802Sjkim * Has no target and the result is not used. Only a couple opcodes 2071167802Sjkim * can have this combination. 2072167802Sjkim */ 2073167802Sjkim switch (Op->Asl.ParseOpcode) 2074167802Sjkim { 2075167802Sjkim case PARSEOP_ACQUIRE: 2076167802Sjkim case PARSEOP_WAIT: 2077167802Sjkim break; 2078167802Sjkim 2079167802Sjkim default: 2080167802Sjkim AslError (ASL_WARNING, ASL_MSG_RESULT_NOT_USED, Op, Op->Asl.ExternalName); 2081167802Sjkim break; 2082167802Sjkim } 2083167802Sjkim } 2084167802Sjkim } 2085167802Sjkim 2086167802Sjkim 2087167802Sjkim /* 2088167802Sjkim * Semantic checks for individual ASL operators 2089167802Sjkim */ 2090167802Sjkim switch (Op->Asl.ParseOpcode) 2091167802Sjkim { 2092167802Sjkim case PARSEOP_ACQUIRE: 2093167802Sjkim case PARSEOP_WAIT: 2094167802Sjkim /* 2095167802Sjkim * Emit a warning if the timeout parameter for these operators is not 2096167802Sjkim * ACPI_WAIT_FOREVER, and the result value from the operator is not 2097167802Sjkim * checked, meaning that a timeout could happen, but the code 2098167802Sjkim * would not know about it. 2099167802Sjkim */ 2100167802Sjkim 2101167802Sjkim /* First child is the namepath, 2nd child is timeout */ 2102167802Sjkim 2103167802Sjkim ArgNode = Op->Asl.Child; 2104167802Sjkim ArgNode = ArgNode->Asl.Next; 2105167802Sjkim 2106167802Sjkim /* 2107167802Sjkim * Check for the WAIT_FOREVER case - defined by the ACPI spec to be 2108167802Sjkim * 0xFFFF or greater 2109167802Sjkim */ 2110167802Sjkim if (((ArgNode->Asl.ParseOpcode == PARSEOP_WORDCONST) || 2111167802Sjkim (ArgNode->Asl.ParseOpcode == PARSEOP_INTEGER)) && 2112167802Sjkim (ArgNode->Asl.Value.Integer >= (ACPI_INTEGER) ACPI_WAIT_FOREVER)) 2113167802Sjkim { 2114167802Sjkim break; 2115167802Sjkim } 2116167802Sjkim 2117167802Sjkim /* 2118167802Sjkim * The operation could timeout. If the return value is not used 2119167802Sjkim * (indicates timeout occurred), issue a warning 2120167802Sjkim */ 2121167802Sjkim if (!AnIsResultUsed (Op)) 2122167802Sjkim { 2123167802Sjkim AslError (ASL_WARNING, ASL_MSG_TIMEOUT, ArgNode, Op->Asl.ExternalName); 2124167802Sjkim } 2125167802Sjkim break; 2126167802Sjkim 2127167802Sjkim case PARSEOP_CREATEFIELD: 2128167802Sjkim /* 2129167802Sjkim * Check for a zero Length (NumBits) operand. NumBits is the 3rd operand 2130167802Sjkim */ 2131167802Sjkim ArgNode = Op->Asl.Child; 2132167802Sjkim ArgNode = ArgNode->Asl.Next; 2133167802Sjkim ArgNode = ArgNode->Asl.Next; 2134167802Sjkim 2135167802Sjkim if ((ArgNode->Asl.ParseOpcode == PARSEOP_ZERO) || 2136167802Sjkim ((ArgNode->Asl.ParseOpcode == PARSEOP_INTEGER) && 2137167802Sjkim (ArgNode->Asl.Value.Integer == 0))) 2138167802Sjkim { 2139167802Sjkim AslError (ASL_ERROR, ASL_MSG_NON_ZERO, ArgNode, NULL); 2140167802Sjkim } 2141167802Sjkim break; 2142167802Sjkim 2143167802Sjkim default: 2144167802Sjkim break; 2145167802Sjkim } 2146167802Sjkim 2147118611Snjl return AE_OK; 2148118611Snjl} 2149118611Snjl 2150118611Snjl 2151118611Snjl/******************************************************************************* 2152118611Snjl * 2153118611Snjl * FUNCTION: AnOtherSemanticAnalysisWalkEnd 2154118611Snjl * 2155118611Snjl * PARAMETERS: ASL_WALK_CALLBACK 2156118611Snjl * 2157118611Snjl * RETURN: Status 2158118611Snjl * 2159167802Sjkim * DESCRIPTION: Ascending callback for analysis walk. Complete method 2160118611Snjl * return analysis. 2161118611Snjl * 2162118611Snjl ******************************************************************************/ 2163118611Snjl 2164118611SnjlACPI_STATUS 2165118611SnjlAnOtherSemanticAnalysisWalkEnd ( 2166118611Snjl ACPI_PARSE_OBJECT *Op, 2167118611Snjl UINT32 Level, 2168118611Snjl void *Context) 2169118611Snjl{ 2170118611Snjl 2171118611Snjl return AE_OK; 2172118611Snjl 2173118611Snjl} 2174151937Sjkim 2175151937Sjkim 2176151937Sjkim#ifdef ACPI_OBSOLETE_FUNCTIONS 2177151937Sjkim/******************************************************************************* 2178151937Sjkim * 2179151937Sjkim * FUNCTION: AnMapBtypeToEtype 2180151937Sjkim * 2181151937Sjkim * PARAMETERS: Btype - Bitfield of ACPI types 2182151937Sjkim * 2183151937Sjkim * RETURN: The Etype corresponding the the Btype 2184151937Sjkim * 2185151937Sjkim * DESCRIPTION: Convert a bitfield type to an encoded type 2186151937Sjkim * 2187151937Sjkim ******************************************************************************/ 2188151937Sjkim 2189151937SjkimUINT32 2190151937SjkimAnMapBtypeToEtype ( 2191151937Sjkim UINT32 Btype) 2192151937Sjkim{ 2193151937Sjkim UINT32 i; 2194151937Sjkim UINT32 Etype; 2195151937Sjkim 2196151937Sjkim 2197151937Sjkim if (Btype == 0) 2198151937Sjkim { 2199151937Sjkim return 0; 2200151937Sjkim } 2201151937Sjkim 2202151937Sjkim Etype = 1; 2203151937Sjkim for (i = 1; i < Btype; i *= 2) 2204151937Sjkim { 2205151937Sjkim Etype++; 2206151937Sjkim } 2207151937Sjkim 2208151937Sjkim return (Etype); 2209151937Sjkim} 2210151937Sjkim#endif 2211151937Sjkim 2212