1218585Sjkim/****************************************************************************** 2218585Sjkim * 3245582Sjkim * Module Name: aslwalks.c - Miscellaneous analytical parse tree walks 4218585Sjkim * 5218585Sjkim *****************************************************************************/ 6218585Sjkim 7218585Sjkim/* 8306536Sjkim * Copyright (C) 2000 - 2016, Intel Corp. 9218585Sjkim * All rights reserved. 10218585Sjkim * 11218585Sjkim * Redistribution and use in source and binary forms, with or without 12218585Sjkim * modification, are permitted provided that the following conditions 13218585Sjkim * are met: 14218585Sjkim * 1. Redistributions of source code must retain the above copyright 15218585Sjkim * notice, this list of conditions, and the following disclaimer, 16218585Sjkim * without modification. 17218585Sjkim * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18218585Sjkim * substantially similar to the "NO WARRANTY" disclaimer below 19218585Sjkim * ("Disclaimer") and any redistribution must be conditioned upon 20218585Sjkim * including a substantially similar Disclaimer requirement for further 21218585Sjkim * binary redistribution. 22218585Sjkim * 3. Neither the names of the above-listed copyright holders nor the names 23218585Sjkim * of any contributors may be used to endorse or promote products derived 24218585Sjkim * from this software without specific prior written permission. 25218585Sjkim * 26218585Sjkim * Alternatively, this software may be distributed under the terms of the 27218585Sjkim * GNU General Public License ("GPL") version 2 as published by the Free 28218585Sjkim * Software Foundation. 29218585Sjkim * 30218585Sjkim * NO WARRANTY 31218585Sjkim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32218585Sjkim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33218585Sjkim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34218585Sjkim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35218585Sjkim * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36218585Sjkim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37218585Sjkim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38218585Sjkim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39218585Sjkim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40218585Sjkim * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41218585Sjkim * POSSIBILITY OF SUCH DAMAGES. 42218585Sjkim */ 43218585Sjkim 44218590Sjkim#include <contrib/dev/acpica/compiler/aslcompiler.h> 45218585Sjkim#include "aslcompiler.y.h" 46218590Sjkim#include <contrib/dev/acpica/include/acparser.h> 47218590Sjkim#include <contrib/dev/acpica/include/amlcode.h> 48218585Sjkim 49218585Sjkim 50218585Sjkim#define _COMPONENT ACPI_COMPILER 51218585Sjkim ACPI_MODULE_NAME ("aslwalks") 52218585Sjkim 53218585Sjkim 54306536Sjkim/* Local prototypes */ 55306536Sjkim 56306536Sjkimstatic void 57306536SjkimAnAnalyzeStoreOperator ( 58306536Sjkim ACPI_PARSE_OBJECT *Op); 59306536Sjkim 60306536Sjkim 61218585Sjkim/******************************************************************************* 62218585Sjkim * 63218585Sjkim * FUNCTION: AnMethodTypingWalkEnd 64218585Sjkim * 65218585Sjkim * PARAMETERS: ASL_WALK_CALLBACK 66218585Sjkim * 67218585Sjkim * RETURN: Status 68218585Sjkim * 69218585Sjkim * DESCRIPTION: Ascending callback for typing walk. Complete the method 70218585Sjkim * return analysis. Check methods for: 71218585Sjkim * 1) Initialized local variables 72218585Sjkim * 2) Valid arguments 73218585Sjkim * 3) Return types 74218585Sjkim * 75218585Sjkim ******************************************************************************/ 76218585Sjkim 77218585SjkimACPI_STATUS 78218585SjkimAnMethodTypingWalkEnd ( 79218585Sjkim ACPI_PARSE_OBJECT *Op, 80218585Sjkim UINT32 Level, 81218585Sjkim void *Context) 82218585Sjkim{ 83306536Sjkim UINT32 ThisOpBtype; 84218585Sjkim 85218585Sjkim 86218585Sjkim switch (Op->Asl.ParseOpcode) 87218585Sjkim { 88218585Sjkim case PARSEOP_METHOD: 89218585Sjkim 90218585Sjkim Op->Asl.CompileFlags |= NODE_METHOD_TYPED; 91218585Sjkim break; 92218585Sjkim 93218585Sjkim case PARSEOP_RETURN: 94218585Sjkim 95218585Sjkim if ((Op->Asl.Child) && 96218585Sjkim (Op->Asl.Child->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG)) 97218585Sjkim { 98306536Sjkim ThisOpBtype = AnGetBtype (Op->Asl.Child); 99218585Sjkim 100218585Sjkim if ((Op->Asl.Child->Asl.ParseOpcode == PARSEOP_METHODCALL) && 101306536Sjkim (ThisOpBtype == (ACPI_UINT32_MAX -1))) 102218585Sjkim { 103218585Sjkim /* 104218585Sjkim * The called method is untyped at this time (typically a 105218585Sjkim * forward reference). 106218585Sjkim * 107306536Sjkim * Check for a recursive method call first. Note: the 108306536Sjkim * Child->Node will be null if the method has not been 109306536Sjkim * resolved. 110218585Sjkim */ 111306536Sjkim if (Op->Asl.Child->Asl.Node && 112306536Sjkim (Op->Asl.ParentMethod != Op->Asl.Child->Asl.Node->Op)) 113218585Sjkim { 114218585Sjkim /* We must type the method here */ 115218585Sjkim 116218585Sjkim TrWalkParseTree (Op->Asl.Child->Asl.Node->Op, 117218585Sjkim ASL_WALK_VISIT_UPWARD, NULL, 118218585Sjkim AnMethodTypingWalkEnd, NULL); 119218585Sjkim 120306536Sjkim ThisOpBtype = AnGetBtype (Op->Asl.Child); 121218585Sjkim } 122218585Sjkim } 123218585Sjkim 124218585Sjkim /* Returns a value, save the value type */ 125218585Sjkim 126218585Sjkim if (Op->Asl.ParentMethod) 127218585Sjkim { 128306536Sjkim Op->Asl.ParentMethod->Asl.AcpiBtype |= ThisOpBtype; 129218585Sjkim } 130218585Sjkim } 131218585Sjkim break; 132218585Sjkim 133218585Sjkim default: 134250838Sjkim 135218585Sjkim break; 136218585Sjkim } 137218585Sjkim 138218585Sjkim return (AE_OK); 139218585Sjkim} 140218585Sjkim 141218585Sjkim 142218585Sjkim/******************************************************************************* 143218585Sjkim * 144218585Sjkim * FUNCTION: AnOperandTypecheckWalkEnd 145218585Sjkim * 146218585Sjkim * PARAMETERS: ASL_WALK_CALLBACK 147218585Sjkim * 148218585Sjkim * RETURN: Status 149218585Sjkim * 150218585Sjkim * DESCRIPTION: Ascending callback for analysis walk. Complete method 151218585Sjkim * return analysis. 152218585Sjkim * 153218585Sjkim ******************************************************************************/ 154218585Sjkim 155218585SjkimACPI_STATUS 156218585SjkimAnOperandTypecheckWalkEnd ( 157218585Sjkim ACPI_PARSE_OBJECT *Op, 158218585Sjkim UINT32 Level, 159218585Sjkim void *Context) 160218585Sjkim{ 161218585Sjkim const ACPI_OPCODE_INFO *OpInfo; 162218585Sjkim UINT32 RuntimeArgTypes; 163218585Sjkim UINT32 RuntimeArgTypes2; 164218585Sjkim UINT32 RequiredBtypes; 165218585Sjkim UINT32 ThisNodeBtype; 166218585Sjkim UINT32 CommonBtypes; 167218585Sjkim UINT32 OpcodeClass; 168218585Sjkim ACPI_PARSE_OBJECT *ArgOp; 169218585Sjkim UINT32 ArgType; 170218585Sjkim 171218585Sjkim 172218585Sjkim switch (Op->Asl.AmlOpcode) 173218585Sjkim { 174218585Sjkim case AML_RAW_DATA_BYTE: 175218585Sjkim case AML_RAW_DATA_WORD: 176218585Sjkim case AML_RAW_DATA_DWORD: 177218585Sjkim case AML_RAW_DATA_QWORD: 178218585Sjkim case AML_RAW_DATA_BUFFER: 179218585Sjkim case AML_RAW_DATA_CHAIN: 180218585Sjkim case AML_PACKAGE_LENGTH: 181218585Sjkim case AML_UNASSIGNED_OPCODE: 182218585Sjkim case AML_DEFAULT_ARG_OP: 183218585Sjkim 184218585Sjkim /* Ignore the internal (compiler-only) AML opcodes */ 185218585Sjkim 186218585Sjkim return (AE_OK); 187218585Sjkim 188218585Sjkim default: 189250838Sjkim 190218585Sjkim break; 191218585Sjkim } 192218585Sjkim 193218585Sjkim OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode); 194218585Sjkim if (!OpInfo) 195218585Sjkim { 196218585Sjkim return (AE_OK); 197218585Sjkim } 198218585Sjkim 199306536Sjkim ArgOp = Op->Asl.Child; 200306536Sjkim OpcodeClass = OpInfo->Class; 201218585Sjkim RuntimeArgTypes = OpInfo->RuntimeArgs; 202218585Sjkim 203218585Sjkim#ifdef ASL_ERROR_NAMED_OBJECT_IN_WHILE 204218585Sjkim /* 205218585Sjkim * Update 11/2008: In practice, we can't perform this check. A simple 206218585Sjkim * analysis is not sufficient. Also, it can cause errors when compiling 207218585Sjkim * disassembled code because of the way Switch operators are implemented 208218585Sjkim * (a While(One) loop with a named temp variable created within.) 209218585Sjkim */ 210218585Sjkim 211218585Sjkim /* 212218585Sjkim * If we are creating a named object, check if we are within a while loop 213218585Sjkim * by checking if the parent is a WHILE op. This is a simple analysis, but 214218585Sjkim * probably sufficient for many cases. 215218585Sjkim * 216218585Sjkim * Allow Scope(), Buffer(), and Package(). 217218585Sjkim */ 218218585Sjkim if (((OpcodeClass == AML_CLASS_NAMED_OBJECT) && (Op->Asl.AmlOpcode != AML_SCOPE_OP)) || 219218585Sjkim ((OpcodeClass == AML_CLASS_CREATE) && (OpInfo->Flags & AML_NSNODE))) 220218585Sjkim { 221218585Sjkim if (Op->Asl.Parent->Asl.AmlOpcode == AML_WHILE_OP) 222218585Sjkim { 223218585Sjkim AslError (ASL_ERROR, ASL_MSG_NAMED_OBJECT_IN_WHILE, Op, NULL); 224218585Sjkim } 225218585Sjkim } 226218585Sjkim#endif 227218585Sjkim 228218585Sjkim /* 229218585Sjkim * Special case for control opcodes IF/RETURN/WHILE since they 230218585Sjkim * have no runtime arg list (at this time) 231218585Sjkim */ 232218585Sjkim switch (Op->Asl.AmlOpcode) 233218585Sjkim { 234218585Sjkim case AML_IF_OP: 235218585Sjkim case AML_WHILE_OP: 236218585Sjkim case AML_RETURN_OP: 237218585Sjkim 238218585Sjkim if (ArgOp->Asl.ParseOpcode == PARSEOP_METHODCALL) 239218585Sjkim { 240218585Sjkim /* Check for an internal method */ 241218585Sjkim 242218585Sjkim if (AnIsInternalMethod (ArgOp)) 243218585Sjkim { 244218585Sjkim return (AE_OK); 245218585Sjkim } 246218585Sjkim 247218585Sjkim /* The lone arg is a method call, check it */ 248218585Sjkim 249218585Sjkim RequiredBtypes = AnMapArgTypeToBtype (ARGI_INTEGER); 250218585Sjkim if (Op->Asl.AmlOpcode == AML_RETURN_OP) 251218585Sjkim { 252218585Sjkim RequiredBtypes = 0xFFFFFFFF; 253218585Sjkim } 254218585Sjkim 255218585Sjkim ThisNodeBtype = AnGetBtype (ArgOp); 256218585Sjkim if (ThisNodeBtype == ACPI_UINT32_MAX) 257218585Sjkim { 258218585Sjkim return (AE_OK); 259218585Sjkim } 260306536Sjkim 261218585Sjkim AnCheckMethodReturnValue (Op, OpInfo, ArgOp, 262218585Sjkim RequiredBtypes, ThisNodeBtype); 263218585Sjkim } 264218585Sjkim return (AE_OK); 265218585Sjkim 266281687Sjkim case AML_EXTERNAL_OP: 267281687Sjkim /* 268281687Sjkim * Not really a "runtime" opcode since it used by disassembler only. 269281687Sjkim * The parser will find any issues with the operands. 270281687Sjkim */ 271281687Sjkim return (AE_OK); 272281687Sjkim 273218585Sjkim default: 274250838Sjkim 275218585Sjkim break; 276218585Sjkim } 277218585Sjkim 278218585Sjkim /* Ignore the non-executable opcodes */ 279218585Sjkim 280218585Sjkim if (RuntimeArgTypes == ARGI_INVALID_OPCODE) 281218585Sjkim { 282218585Sjkim return (AE_OK); 283218585Sjkim } 284218585Sjkim 285306536Sjkim /* 286306536Sjkim * Special handling for certain opcodes. 287306536Sjkim */ 288306536Sjkim switch (Op->Asl.AmlOpcode) 289306536Sjkim { 290306536Sjkim /* BankField has one TermArg */ 291306536Sjkim 292306536Sjkim case AML_BANK_FIELD_OP: 293306536Sjkim 294306536Sjkim OpcodeClass = AML_CLASS_EXECUTE; 295306536Sjkim ArgOp = ArgOp->Asl.Next; 296306536Sjkim ArgOp = ArgOp->Asl.Next; 297306536Sjkim break; 298306536Sjkim 299306536Sjkim /* Operation Region has 2 TermArgs */ 300306536Sjkim 301306536Sjkim case AML_REGION_OP: 302306536Sjkim 303306536Sjkim OpcodeClass = AML_CLASS_EXECUTE; 304306536Sjkim ArgOp = ArgOp->Asl.Next; 305306536Sjkim ArgOp = ArgOp->Asl.Next; 306306536Sjkim break; 307306536Sjkim 308306536Sjkim /* DataTableRegion has 3 TermArgs */ 309306536Sjkim 310306536Sjkim case AML_DATA_REGION_OP: 311306536Sjkim 312306536Sjkim OpcodeClass = AML_CLASS_EXECUTE; 313306536Sjkim ArgOp = ArgOp->Asl.Next; 314306536Sjkim break; 315306536Sjkim 316306536Sjkim /* Buffers/Packages have a length that is a TermArg */ 317306536Sjkim 318306536Sjkim case AML_BUFFER_OP: 319306536Sjkim case AML_PACKAGE_OP: 320306536Sjkim case AML_VAR_PACKAGE_OP: 321306536Sjkim 322306536Sjkim /* If length is a constant, we are done */ 323306536Sjkim 324306536Sjkim if ((ArgOp->Asl.ParseOpcode == PARSEOP_INTEGER) || 325306536Sjkim (ArgOp->Asl.ParseOpcode == PARSEOP_RAW_DATA)) 326306536Sjkim { 327306536Sjkim return (AE_OK); 328306536Sjkim } 329306536Sjkim break; 330306536Sjkim 331306536Sjkim /* Store can write any object to the Debug object */ 332306536Sjkim 333306536Sjkim case AML_STORE_OP: 334306536Sjkim /* 335306536Sjkim * If this is a Store() to the Debug object, we don't need 336306536Sjkim * to perform any further validation -- because a Store of 337306536Sjkim * any object to Debug is permitted and supported. 338306536Sjkim */ 339306536Sjkim if (ArgOp->Asl.Next->Asl.AmlOpcode == AML_DEBUG_OP) 340306536Sjkim { 341306536Sjkim return (AE_OK); 342306536Sjkim } 343306536Sjkim break; 344306536Sjkim 345306536Sjkim default: 346306536Sjkim break; 347306536Sjkim } 348306536Sjkim 349218585Sjkim switch (OpcodeClass) 350218585Sjkim { 351218585Sjkim case AML_CLASS_EXECUTE: 352218585Sjkim case AML_CLASS_CREATE: 353218585Sjkim case AML_CLASS_CONTROL: 354218585Sjkim case AML_CLASS_RETURN_VALUE: 355218585Sjkim 356218585Sjkim /* Reverse the runtime argument list */ 357218585Sjkim 358218585Sjkim RuntimeArgTypes2 = 0; 359218585Sjkim while ((ArgType = GET_CURRENT_ARG_TYPE (RuntimeArgTypes))) 360218585Sjkim { 361218585Sjkim RuntimeArgTypes2 <<= ARG_TYPE_WIDTH; 362218585Sjkim RuntimeArgTypes2 |= ArgType; 363218585Sjkim INCREMENT_ARG_LIST (RuntimeArgTypes); 364218585Sjkim } 365218585Sjkim 366306536Sjkim /* Typecheck each argument */ 367306536Sjkim 368218585Sjkim while ((ArgType = GET_CURRENT_ARG_TYPE (RuntimeArgTypes2))) 369218585Sjkim { 370306536Sjkim /* Get the required type(s) for the argument */ 371306536Sjkim 372218585Sjkim RequiredBtypes = AnMapArgTypeToBtype (ArgType); 373218585Sjkim 374281075Sdim if (!ArgOp) 375281075Sdim { 376281075Sdim AslError (ASL_ERROR, ASL_MSG_COMPILER_INTERNAL, Op, 377281075Sdim "Null ArgOp in argument loop"); 378281075Sdim AslAbort (); 379281075Sdim } 380281075Sdim 381306536Sjkim /* Get the actual type of the argument */ 382306536Sjkim 383218585Sjkim ThisNodeBtype = AnGetBtype (ArgOp); 384218585Sjkim if (ThisNodeBtype == ACPI_UINT32_MAX) 385218585Sjkim { 386218585Sjkim goto NextArgument; 387218585Sjkim } 388218585Sjkim 389218585Sjkim /* Examine the arg based on the required type of the arg */ 390218585Sjkim 391218585Sjkim switch (ArgType) 392218585Sjkim { 393218585Sjkim case ARGI_TARGETREF: 394218585Sjkim 395218585Sjkim if (ArgOp->Asl.ParseOpcode == PARSEOP_ZERO) 396218585Sjkim { 397218585Sjkim /* ZERO is the placeholder for "don't store result" */ 398218585Sjkim 399218585Sjkim ThisNodeBtype = RequiredBtypes; 400218585Sjkim break; 401218585Sjkim } 402218585Sjkim 403306536Sjkim /* Fallthrough */ 404306536Sjkim 405306536Sjkim case ARGI_STORE_TARGET: 406306536Sjkim 407218585Sjkim if (ArgOp->Asl.ParseOpcode == PARSEOP_INTEGER) 408218585Sjkim { 409218585Sjkim /* 410218585Sjkim * This is the case where an original reference to a resource 411218585Sjkim * descriptor field has been replaced by an (Integer) offset. 412218585Sjkim * These named fields are supported at compile-time only; 413218585Sjkim * the names are not passed to the interpreter (via the AML). 414218585Sjkim */ 415218585Sjkim if ((ArgOp->Asl.Node->Type == ACPI_TYPE_LOCAL_RESOURCE_FIELD) || 416218585Sjkim (ArgOp->Asl.Node->Type == ACPI_TYPE_LOCAL_RESOURCE)) 417218585Sjkim { 418306536Sjkim AslError (ASL_ERROR, ASL_MSG_RESOURCE_FIELD, 419306536Sjkim ArgOp, NULL); 420218585Sjkim } 421218585Sjkim else 422218585Sjkim { 423306536Sjkim AslError (ASL_ERROR, ASL_MSG_INVALID_TYPE, 424306536Sjkim ArgOp, NULL); 425218585Sjkim } 426218585Sjkim } 427218585Sjkim break; 428218585Sjkim 429218585Sjkim 430306536Sjkim#ifdef __FUTURE_IMPLEMENTATION 431306536Sjkim/* 432306536Sjkim * Possible future typechecking support 433306536Sjkim */ 434218585Sjkim case ARGI_REFERENCE: /* References */ 435218585Sjkim case ARGI_INTEGER_REF: 436218585Sjkim case ARGI_OBJECT_REF: 437218585Sjkim case ARGI_DEVICE_REF: 438218585Sjkim 439218585Sjkim switch (ArgOp->Asl.ParseOpcode) 440218585Sjkim { 441218585Sjkim case PARSEOP_LOCAL0: 442218585Sjkim case PARSEOP_LOCAL1: 443218585Sjkim case PARSEOP_LOCAL2: 444218585Sjkim case PARSEOP_LOCAL3: 445218585Sjkim case PARSEOP_LOCAL4: 446218585Sjkim case PARSEOP_LOCAL5: 447218585Sjkim case PARSEOP_LOCAL6: 448218585Sjkim case PARSEOP_LOCAL7: 449218585Sjkim 450218585Sjkim /* TBD: implement analysis of current value (type) of the local */ 451218585Sjkim /* For now, just treat any local as a typematch */ 452218585Sjkim 453218585Sjkim /*ThisNodeBtype = RequiredBtypes;*/ 454218585Sjkim break; 455218585Sjkim 456218585Sjkim case PARSEOP_ARG0: 457218585Sjkim case PARSEOP_ARG1: 458218585Sjkim case PARSEOP_ARG2: 459218585Sjkim case PARSEOP_ARG3: 460218585Sjkim case PARSEOP_ARG4: 461218585Sjkim case PARSEOP_ARG5: 462218585Sjkim case PARSEOP_ARG6: 463218585Sjkim 464306536Sjkim /* Hard to analyze argument types, so we won't */ 465306536Sjkim /* for now. Just treat any arg as a typematch */ 466218585Sjkim 467218585Sjkim /* ThisNodeBtype = RequiredBtypes; */ 468218585Sjkim break; 469218585Sjkim 470218585Sjkim case PARSEOP_DEBUG: 471218585Sjkim case PARSEOP_REFOF: 472218585Sjkim case PARSEOP_INDEX: 473218585Sjkim default: 474250838Sjkim 475218585Sjkim break; 476218585Sjkim } 477218585Sjkim break; 478306536Sjkim#endif 479218585Sjkim case ARGI_INTEGER: 480218585Sjkim default: 481250838Sjkim 482218585Sjkim break; 483218585Sjkim } 484218585Sjkim 485218585Sjkim 486306536Sjkim /* Check for a type mismatch (required versus actual) */ 487306536Sjkim 488218585Sjkim CommonBtypes = ThisNodeBtype & RequiredBtypes; 489218585Sjkim 490218585Sjkim if (ArgOp->Asl.ParseOpcode == PARSEOP_METHODCALL) 491218585Sjkim { 492218585Sjkim if (AnIsInternalMethod (ArgOp)) 493218585Sjkim { 494218585Sjkim return (AE_OK); 495218585Sjkim } 496218585Sjkim 497218585Sjkim /* Check a method call for a valid return value */ 498218585Sjkim 499218585Sjkim AnCheckMethodReturnValue (Op, OpInfo, ArgOp, 500218585Sjkim RequiredBtypes, ThisNodeBtype); 501218585Sjkim } 502218585Sjkim 503218585Sjkim /* 504218585Sjkim * Now check if the actual type(s) match at least one 505218585Sjkim * bit to the required type 506218585Sjkim */ 507218585Sjkim else if (!CommonBtypes) 508218585Sjkim { 509218585Sjkim /* No match -- this is a type mismatch error */ 510218585Sjkim 511218585Sjkim AnFormatBtype (StringBuffer, ThisNodeBtype); 512218585Sjkim AnFormatBtype (StringBuffer2, RequiredBtypes); 513218585Sjkim 514218585Sjkim sprintf (MsgBuffer, "[%s] found, %s operator requires [%s]", 515306536Sjkim StringBuffer, OpInfo->Name, StringBuffer2); 516218585Sjkim 517306536Sjkim AslError (ASL_ERROR, ASL_MSG_INVALID_TYPE, 518306536Sjkim ArgOp, MsgBuffer); 519218585Sjkim } 520218585Sjkim 521218585Sjkim NextArgument: 522218585Sjkim ArgOp = ArgOp->Asl.Next; 523218585Sjkim INCREMENT_ARG_LIST (RuntimeArgTypes2); 524218585Sjkim } 525218585Sjkim break; 526218585Sjkim 527218585Sjkim default: 528250838Sjkim 529218585Sjkim break; 530218585Sjkim } 531218585Sjkim 532218585Sjkim return (AE_OK); 533218585Sjkim} 534218585Sjkim 535218585Sjkim 536218585Sjkim/******************************************************************************* 537218585Sjkim * 538218585Sjkim * FUNCTION: AnOtherSemanticAnalysisWalkBegin 539218585Sjkim * 540218585Sjkim * PARAMETERS: ASL_WALK_CALLBACK 541218585Sjkim * 542218585Sjkim * RETURN: Status 543218585Sjkim * 544218585Sjkim * DESCRIPTION: Descending callback for the analysis walk. Checks for 545218585Sjkim * miscellaneous issues in the code. 546218585Sjkim * 547218585Sjkim ******************************************************************************/ 548218585Sjkim 549218585SjkimACPI_STATUS 550218585SjkimAnOtherSemanticAnalysisWalkBegin ( 551218585Sjkim ACPI_PARSE_OBJECT *Op, 552218585Sjkim UINT32 Level, 553218585Sjkim void *Context) 554218585Sjkim{ 555306536Sjkim ACPI_PARSE_OBJECT *ArgOp; 556306536Sjkim ACPI_PARSE_OBJECT *PrevArgOp = NULL; 557218585Sjkim const ACPI_OPCODE_INFO *OpInfo; 558228110Sjkim ACPI_NAMESPACE_NODE *Node; 559218585Sjkim 560218585Sjkim 561218585Sjkim OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode); 562218585Sjkim 563306536Sjkim 564218585Sjkim /* 565218585Sjkim * Determine if an execution class operator actually does something by 566218585Sjkim * checking if it has a target and/or the function return value is used. 567218585Sjkim * (Target is optional, so a standalone statement can actually do nothing.) 568218585Sjkim */ 569218585Sjkim if ((OpInfo->Class == AML_CLASS_EXECUTE) && 570218585Sjkim (OpInfo->Flags & AML_HAS_RETVAL) && 571218585Sjkim (!AnIsResultUsed (Op))) 572218585Sjkim { 573218585Sjkim if (OpInfo->Flags & AML_HAS_TARGET) 574218585Sjkim { 575218585Sjkim /* 576306536Sjkim * Find the target node, it is always the last child. If the target 577218585Sjkim * is not specified in the ASL, a default node of type Zero was 578218585Sjkim * created by the parser. 579218585Sjkim */ 580306536Sjkim ArgOp = Op->Asl.Child; 581306536Sjkim while (ArgOp->Asl.Next) 582218585Sjkim { 583306536Sjkim PrevArgOp = ArgOp; 584306536Sjkim ArgOp = ArgOp->Asl.Next; 585218585Sjkim } 586218585Sjkim 587218585Sjkim /* Divide() is the only weird case, it has two targets */ 588218585Sjkim 589218585Sjkim if (Op->Asl.AmlOpcode == AML_DIVIDE_OP) 590218585Sjkim { 591306536Sjkim if ((ArgOp->Asl.ParseOpcode == PARSEOP_ZERO) && 592306536Sjkim (PrevArgOp) && 593306536Sjkim (PrevArgOp->Asl.ParseOpcode == PARSEOP_ZERO)) 594218585Sjkim { 595249112Sjkim AslError (ASL_ERROR, ASL_MSG_RESULT_NOT_USED, 596218585Sjkim Op, Op->Asl.ExternalName); 597218585Sjkim } 598218585Sjkim } 599306536Sjkim 600306536Sjkim else if (ArgOp->Asl.ParseOpcode == PARSEOP_ZERO) 601218585Sjkim { 602249112Sjkim AslError (ASL_ERROR, ASL_MSG_RESULT_NOT_USED, 603218585Sjkim Op, Op->Asl.ExternalName); 604218585Sjkim } 605218585Sjkim } 606218585Sjkim else 607218585Sjkim { 608218585Sjkim /* 609218585Sjkim * Has no target and the result is not used. Only a couple opcodes 610218585Sjkim * can have this combination. 611218585Sjkim */ 612218585Sjkim switch (Op->Asl.ParseOpcode) 613218585Sjkim { 614218585Sjkim case PARSEOP_ACQUIRE: 615218585Sjkim case PARSEOP_WAIT: 616218585Sjkim case PARSEOP_LOADTABLE: 617250838Sjkim 618218585Sjkim break; 619218585Sjkim 620218585Sjkim default: 621250838Sjkim 622249112Sjkim AslError (ASL_ERROR, ASL_MSG_RESULT_NOT_USED, 623218585Sjkim Op, Op->Asl.ExternalName); 624218585Sjkim break; 625218585Sjkim } 626218585Sjkim } 627218585Sjkim } 628218585Sjkim 629218585Sjkim 630218585Sjkim /* 631218585Sjkim * Semantic checks for individual ASL operators 632218585Sjkim */ 633218585Sjkim switch (Op->Asl.ParseOpcode) 634218585Sjkim { 635306536Sjkim case PARSEOP_STORE: 636306536Sjkim 637306536Sjkim if (Gbl_DoTypechecking) 638306536Sjkim { 639306536Sjkim AnAnalyzeStoreOperator (Op); 640306536Sjkim } 641306536Sjkim break; 642306536Sjkim 643306536Sjkim 644218585Sjkim case PARSEOP_ACQUIRE: 645218585Sjkim case PARSEOP_WAIT: 646218585Sjkim /* 647218585Sjkim * Emit a warning if the timeout parameter for these operators is not 648218585Sjkim * ACPI_WAIT_FOREVER, and the result value from the operator is not 649218585Sjkim * checked, meaning that a timeout could happen, but the code 650218585Sjkim * would not know about it. 651218585Sjkim */ 652218585Sjkim 653218585Sjkim /* First child is the namepath, 2nd child is timeout */ 654218585Sjkim 655306536Sjkim ArgOp = Op->Asl.Child; 656306536Sjkim ArgOp = ArgOp->Asl.Next; 657218585Sjkim 658218585Sjkim /* 659218585Sjkim * Check for the WAIT_FOREVER case - defined by the ACPI spec to be 660218585Sjkim * 0xFFFF or greater 661218585Sjkim */ 662306536Sjkim if (((ArgOp->Asl.ParseOpcode == PARSEOP_WORDCONST) || 663306536Sjkim (ArgOp->Asl.ParseOpcode == PARSEOP_INTEGER)) && 664306536Sjkim (ArgOp->Asl.Value.Integer >= (UINT64) ACPI_WAIT_FOREVER)) 665218585Sjkim { 666218585Sjkim break; 667218585Sjkim } 668218585Sjkim 669218585Sjkim /* 670218585Sjkim * The operation could timeout. If the return value is not used 671218585Sjkim * (indicates timeout occurred), issue a warning 672218585Sjkim */ 673218585Sjkim if (!AnIsResultUsed (Op)) 674218585Sjkim { 675306536Sjkim AslError (ASL_WARNING, ASL_MSG_TIMEOUT, ArgOp, 676218585Sjkim Op->Asl.ExternalName); 677218585Sjkim } 678218585Sjkim break; 679218585Sjkim 680218585Sjkim case PARSEOP_CREATEFIELD: 681218585Sjkim /* 682218585Sjkim * Check for a zero Length (NumBits) operand. NumBits is the 3rd operand 683218585Sjkim */ 684306536Sjkim ArgOp = Op->Asl.Child; 685306536Sjkim ArgOp = ArgOp->Asl.Next; 686306536Sjkim ArgOp = ArgOp->Asl.Next; 687218585Sjkim 688306536Sjkim if ((ArgOp->Asl.ParseOpcode == PARSEOP_ZERO) || 689306536Sjkim ((ArgOp->Asl.ParseOpcode == PARSEOP_INTEGER) && 690306536Sjkim (ArgOp->Asl.Value.Integer == 0))) 691218585Sjkim { 692306536Sjkim AslError (ASL_ERROR, ASL_MSG_NON_ZERO, ArgOp, NULL); 693218585Sjkim } 694218585Sjkim break; 695218585Sjkim 696228110Sjkim case PARSEOP_CONNECTION: 697228110Sjkim /* 698228110Sjkim * Ensure that the referenced operation region has the correct SPACE_ID. 699228110Sjkim * From the grammar/parser, we know the parent is a FIELD definition. 700228110Sjkim */ 701306536Sjkim ArgOp = Op->Asl.Parent; /* Field definition */ 702306536Sjkim ArgOp = ArgOp->Asl.Child; /* First child is the OpRegion Name */ 703306536Sjkim Node = ArgOp->Asl.Node; /* OpRegion namespace node */ 704281075Sdim if (!Node) 705281075Sdim { 706281075Sdim break; 707281075Sdim } 708228110Sjkim 709306536Sjkim ArgOp = Node->Op; /* OpRegion definition */ 710306536Sjkim ArgOp = ArgOp->Asl.Child; /* First child is the OpRegion Name */ 711306536Sjkim ArgOp = ArgOp->Asl.Next; /* Next peer is the SPACE_ID (what we want) */ 712228110Sjkim 713228110Sjkim /* 714228110Sjkim * The Connection() operator is only valid for the following operation 715228110Sjkim * region SpaceIds: GeneralPurposeIo and GenericSerialBus. 716228110Sjkim */ 717306536Sjkim if ((ArgOp->Asl.Value.Integer != ACPI_ADR_SPACE_GPIO) && 718306536Sjkim (ArgOp->Asl.Value.Integer != ACPI_ADR_SPACE_GSBUS)) 719228110Sjkim { 720228110Sjkim AslError (ASL_ERROR, ASL_MSG_CONNECTION_INVALID, Op, NULL); 721228110Sjkim } 722228110Sjkim break; 723228110Sjkim 724228110Sjkim case PARSEOP_FIELD: 725228110Sjkim /* 726228110Sjkim * Ensure that fields for GeneralPurposeIo and GenericSerialBus 727228110Sjkim * contain at least one Connection() operator 728228110Sjkim */ 729306536Sjkim ArgOp = Op->Asl.Child; /* 1st child is the OpRegion Name */ 730306536Sjkim Node = ArgOp->Asl.Node; /* OpRegion namespace node */ 731228110Sjkim if (!Node) 732228110Sjkim { 733228110Sjkim break; 734228110Sjkim } 735228110Sjkim 736306536Sjkim ArgOp = Node->Op; /* OpRegion definition */ 737306536Sjkim ArgOp = ArgOp->Asl.Child; /* First child is the OpRegion Name */ 738306536Sjkim ArgOp = ArgOp->Asl.Next; /* Next peer is the SPACE_ID (what we want) */ 739228110Sjkim 740228110Sjkim /* We are only interested in GeneralPurposeIo and GenericSerialBus */ 741228110Sjkim 742306536Sjkim if ((ArgOp->Asl.Value.Integer != ACPI_ADR_SPACE_GPIO) && 743306536Sjkim (ArgOp->Asl.Value.Integer != ACPI_ADR_SPACE_GSBUS)) 744228110Sjkim { 745228110Sjkim break; 746228110Sjkim } 747228110Sjkim 748306536Sjkim ArgOp = Op->Asl.Child; /* 1st child is the OpRegion Name */ 749306536Sjkim ArgOp = ArgOp->Asl.Next; /* AccessType */ 750306536Sjkim ArgOp = ArgOp->Asl.Next; /* LockRule */ 751306536Sjkim ArgOp = ArgOp->Asl.Next; /* UpdateRule */ 752306536Sjkim ArgOp = ArgOp->Asl.Next; /* Start of FieldUnitList */ 753228110Sjkim 754228110Sjkim /* Walk the FieldUnitList */ 755228110Sjkim 756306536Sjkim while (ArgOp) 757228110Sjkim { 758306536Sjkim if (ArgOp->Asl.ParseOpcode == PARSEOP_CONNECTION) 759228110Sjkim { 760228110Sjkim break; 761228110Sjkim } 762306536Sjkim else if (ArgOp->Asl.ParseOpcode == PARSEOP_NAMESEG) 763228110Sjkim { 764306536Sjkim AslError (ASL_ERROR, ASL_MSG_CONNECTION_MISSING, ArgOp, NULL); 765228110Sjkim break; 766228110Sjkim } 767228110Sjkim 768306536Sjkim ArgOp = ArgOp->Asl.Next; 769228110Sjkim } 770228110Sjkim break; 771228110Sjkim 772218585Sjkim default: 773250838Sjkim 774218585Sjkim break; 775218585Sjkim } 776218585Sjkim 777218585Sjkim return (AE_OK); 778218585Sjkim} 779306536Sjkim 780306536Sjkim 781306536Sjkim/******************************************************************************* 782306536Sjkim * 783306536Sjkim * FUNCTION: AnAnalyzeStoreOperator 784306536Sjkim * 785306536Sjkim * PARAMETERS: Op - Store() operator 786306536Sjkim * 787306536Sjkim * RETURN: None 788306536Sjkim * 789306536Sjkim * DESCRIPTION: Analyze a store operator. Mostly for stores to/from package 790306536Sjkim * objects where there are more restrictions than other data 791306536Sjkim * types. 792306536Sjkim * 793306536Sjkim ******************************************************************************/ 794306536Sjkim 795306536Sjkimstatic void 796306536SjkimAnAnalyzeStoreOperator ( 797306536Sjkim ACPI_PARSE_OBJECT *Op) 798306536Sjkim{ 799306536Sjkim ACPI_NAMESPACE_NODE *SourceNode; 800306536Sjkim ACPI_NAMESPACE_NODE *TargetNode; 801306536Sjkim ACPI_PARSE_OBJECT *SourceOperandOp; 802306536Sjkim ACPI_PARSE_OBJECT *TargetOperandOp; 803306536Sjkim UINT32 SourceOperandBtype; 804306536Sjkim UINT32 TargetOperandBtype; 805306536Sjkim 806306536Sjkim 807306536Sjkim /* Extract the two operands for STORE */ 808306536Sjkim 809306536Sjkim SourceOperandOp = Op->Asl.Child; 810306536Sjkim TargetOperandOp = SourceOperandOp->Asl.Next; 811306536Sjkim 812306536Sjkim /* 813306536Sjkim * Ignore these Source operand opcodes, they cannot be typechecked, 814306536Sjkim * the actual result is unknown here. 815306536Sjkim */ 816306536Sjkim switch (SourceOperandOp->Asl.ParseOpcode) 817306536Sjkim { 818306536Sjkim /* For these, type of the returned value is unknown at compile time */ 819306536Sjkim 820306536Sjkim case PARSEOP_DEREFOF: 821306536Sjkim case PARSEOP_METHODCALL: 822306536Sjkim case PARSEOP_STORE: 823306536Sjkim case PARSEOP_COPYOBJECT: 824306536Sjkim 825306536Sjkim return; 826306536Sjkim 827306536Sjkim case PARSEOP_INDEX: 828306536Sjkim case PARSEOP_REFOF: 829306536Sjkim 830306536Sjkim if (!Gbl_EnableReferenceTypechecking) 831306536Sjkim { 832306536Sjkim return; 833306536Sjkim } 834306536Sjkim 835306536Sjkim /* 836306536Sjkim * These opcodes always return an object reference, and thus 837306536Sjkim * the result can only be stored to a Local, Arg, or Debug. 838306536Sjkim */ 839306536Sjkim if (TargetOperandOp->Asl.AmlOpcode == AML_DEBUG_OP) 840306536Sjkim { 841306536Sjkim return; 842306536Sjkim } 843306536Sjkim 844306536Sjkim if ((TargetOperandOp->Asl.AmlOpcode < AML_LOCAL0) || 845306536Sjkim (TargetOperandOp->Asl.AmlOpcode > AML_ARG6)) 846306536Sjkim { 847306536Sjkim AslError (ASL_ERROR, ASL_MSG_INVALID_TYPE, TargetOperandOp, 848306536Sjkim "Source [Reference], Target must be [Local/Arg/Debug]"); 849306536Sjkim } 850306536Sjkim return; 851306536Sjkim 852306536Sjkim default: 853306536Sjkim break; 854306536Sjkim } 855306536Sjkim 856306536Sjkim /* 857306536Sjkim * Ignore these Target operand opcodes, they cannot be typechecked 858306536Sjkim */ 859306536Sjkim switch (TargetOperandOp->Asl.ParseOpcode) 860306536Sjkim { 861306536Sjkim case PARSEOP_DEBUG: 862306536Sjkim case PARSEOP_DEREFOF: 863306536Sjkim case PARSEOP_REFOF: 864306536Sjkim case PARSEOP_INDEX: 865306536Sjkim 866306536Sjkim return; 867306536Sjkim 868306536Sjkim case PARSEOP_METHODCALL: 869306536Sjkim /* 870306536Sjkim * A target is not allowed to be a method call. 871306536Sjkim * It is not supported by the ACPICA interpreter, nor is it 872306536Sjkim * supported by the MS ASL compiler or the MS interpreter. 873306536Sjkim * Although legal syntax up until ACPI 6.1, support for this 874306536Sjkim * will be removed for ACPI 6.2 (02/2016) 875306536Sjkim */ 876306536Sjkim AslError (ASL_ERROR, ASL_MSG_SYNTAX, 877306536Sjkim TargetOperandOp, "Illegal method invocation as a target operand"); 878306536Sjkim return; 879306536Sjkim 880306536Sjkim default: 881306536Sjkim break; 882306536Sjkim } 883306536Sjkim 884306536Sjkim /* 885306536Sjkim * Ignore typecheck for External() operands of type "UnknownObj", 886306536Sjkim * we don't know the actual type (source or target). 887306536Sjkim */ 888306536Sjkim SourceNode = SourceOperandOp->Asl.Node; 889306536Sjkim if (SourceNode && 890306536Sjkim (SourceNode->Flags & ANOBJ_IS_EXTERNAL) && 891306536Sjkim (SourceNode->Type == ACPI_TYPE_ANY)) 892306536Sjkim { 893306536Sjkim return; 894306536Sjkim } 895306536Sjkim 896306536Sjkim TargetNode = TargetOperandOp->Asl.Node; 897306536Sjkim if (TargetNode && 898306536Sjkim (TargetNode->Flags & ANOBJ_IS_EXTERNAL) && 899306536Sjkim (TargetNode->Type == ACPI_TYPE_ANY)) 900306536Sjkim { 901306536Sjkim return; 902306536Sjkim } 903306536Sjkim 904306536Sjkim /* 905306536Sjkim * A NULL node with a namepath AML opcode indicates non-existent 906306536Sjkim * name. Just return, the error message is generated elsewhere. 907306536Sjkim */ 908306536Sjkim if ((!SourceNode && (SourceOperandOp->Asl.AmlOpcode == AML_INT_NAMEPATH_OP)) || 909306536Sjkim (!TargetNode && (TargetOperandOp->Asl.AmlOpcode == AML_INT_NAMEPATH_OP))) 910306536Sjkim { 911306536Sjkim return; 912306536Sjkim } 913306536Sjkim 914306536Sjkim /* 915306536Sjkim * Simple check for source same as target via NS node. 916306536Sjkim * -- Could be expanded to locals and args. 917306536Sjkim */ 918306536Sjkim if (SourceNode && TargetNode) 919306536Sjkim { 920306536Sjkim if (SourceNode == TargetNode) 921306536Sjkim { 922306536Sjkim AslError (ASL_WARNING, ASL_MSG_DUPLICATE_ITEM, 923306536Sjkim TargetOperandOp, "Source is the same as Target"); 924306536Sjkim return; 925306536Sjkim } 926306536Sjkim } 927306536Sjkim 928306536Sjkim /* Ignore typecheck if either source or target is a local or arg */ 929306536Sjkim 930306536Sjkim if ((SourceOperandOp->Asl.AmlOpcode >= AML_LOCAL0) && 931306536Sjkim (SourceOperandOp->Asl.AmlOpcode <= AML_ARG6)) 932306536Sjkim { 933306536Sjkim return; /* Cannot type a local/arg at compile time */ 934306536Sjkim } 935306536Sjkim 936306536Sjkim if ((TargetOperandOp->Asl.AmlOpcode >= AML_LOCAL0) && 937306536Sjkim (TargetOperandOp->Asl.AmlOpcode <= AML_ARG6)) 938306536Sjkim { 939306536Sjkim return; /* Cannot type a local/arg at compile time */ 940306536Sjkim } 941306536Sjkim 942306536Sjkim /* 943306536Sjkim * Package objects are a special case because they cannot by implicitly 944306536Sjkim * converted to/from anything. Check for these two illegal cases: 945306536Sjkim * 946306536Sjkim * Store (non-package, package) 947306536Sjkim * Store (package, non-package) 948306536Sjkim */ 949306536Sjkim SourceOperandBtype = AnGetBtype (SourceOperandOp); 950306536Sjkim TargetOperandBtype = AnGetBtype (TargetOperandOp); 951306536Sjkim 952306536Sjkim /* Check source first for (package, non-package) case */ 953306536Sjkim 954306536Sjkim if (SourceOperandBtype & ACPI_BTYPE_PACKAGE) 955306536Sjkim { 956306536Sjkim /* If Source is PACKAGE-->Target must be PACKAGE */ 957306536Sjkim 958306536Sjkim if (!(TargetOperandBtype & ACPI_BTYPE_PACKAGE)) 959306536Sjkim { 960306536Sjkim AslError (ASL_ERROR, ASL_MSG_INVALID_TYPE, TargetOperandOp, 961306536Sjkim "Source is [Package], Target must be a package also"); 962306536Sjkim } 963306536Sjkim } 964306536Sjkim 965306536Sjkim /* Else check target for (non-package, package) case */ 966306536Sjkim 967306536Sjkim else if (TargetOperandBtype & ACPI_BTYPE_PACKAGE) 968306536Sjkim { 969306536Sjkim /* If Target is PACKAGE, Source must be PACKAGE */ 970306536Sjkim 971306536Sjkim if (!(SourceOperandBtype & ACPI_BTYPE_PACKAGE)) 972306536Sjkim { 973306536Sjkim AslError (ASL_ERROR, ASL_MSG_INVALID_TYPE, SourceOperandOp, 974306536Sjkim "Target is [Package], Source must be a package also"); 975306536Sjkim } 976306536Sjkim } 977306536Sjkim} 978