10b94ba42SJung-uk Kim /****************************************************************************** 20b94ba42SJung-uk Kim * 3efcc2a30SJung-uk Kim * Module Name: aslwalks.c - Miscellaneous analytical parse tree walks 40b94ba42SJung-uk Kim * 50b94ba42SJung-uk Kim *****************************************************************************/ 60b94ba42SJung-uk Kim 70b94ba42SJung-uk Kim /* 8f8146b88SJung-uk Kim * Copyright (C) 2000 - 2016, Intel Corp. 90b94ba42SJung-uk Kim * All rights reserved. 100b94ba42SJung-uk Kim * 110b94ba42SJung-uk Kim * Redistribution and use in source and binary forms, with or without 120b94ba42SJung-uk Kim * modification, are permitted provided that the following conditions 130b94ba42SJung-uk Kim * are met: 140b94ba42SJung-uk Kim * 1. Redistributions of source code must retain the above copyright 150b94ba42SJung-uk Kim * notice, this list of conditions, and the following disclaimer, 160b94ba42SJung-uk Kim * without modification. 170b94ba42SJung-uk Kim * 2. Redistributions in binary form must reproduce at minimum a disclaimer 180b94ba42SJung-uk Kim * substantially similar to the "NO WARRANTY" disclaimer below 190b94ba42SJung-uk Kim * ("Disclaimer") and any redistribution must be conditioned upon 200b94ba42SJung-uk Kim * including a substantially similar Disclaimer requirement for further 210b94ba42SJung-uk Kim * binary redistribution. 220b94ba42SJung-uk Kim * 3. Neither the names of the above-listed copyright holders nor the names 230b94ba42SJung-uk Kim * of any contributors may be used to endorse or promote products derived 240b94ba42SJung-uk Kim * from this software without specific prior written permission. 250b94ba42SJung-uk Kim * 260b94ba42SJung-uk Kim * Alternatively, this software may be distributed under the terms of the 270b94ba42SJung-uk Kim * GNU General Public License ("GPL") version 2 as published by the Free 280b94ba42SJung-uk Kim * Software Foundation. 290b94ba42SJung-uk Kim * 300b94ba42SJung-uk Kim * NO WARRANTY 310b94ba42SJung-uk Kim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 320b94ba42SJung-uk Kim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 330b94ba42SJung-uk Kim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 340b94ba42SJung-uk Kim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 350b94ba42SJung-uk Kim * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 360b94ba42SJung-uk Kim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 370b94ba42SJung-uk Kim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 380b94ba42SJung-uk Kim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 390b94ba42SJung-uk Kim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 400b94ba42SJung-uk Kim * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 410b94ba42SJung-uk Kim * POSSIBILITY OF SUCH DAMAGES. 420b94ba42SJung-uk Kim */ 430b94ba42SJung-uk Kim 440b94ba42SJung-uk Kim #include <contrib/dev/acpica/compiler/aslcompiler.h> 450b94ba42SJung-uk Kim #include "aslcompiler.y.h" 460b94ba42SJung-uk Kim #include <contrib/dev/acpica/include/acparser.h> 470b94ba42SJung-uk Kim #include <contrib/dev/acpica/include/amlcode.h> 480b94ba42SJung-uk Kim 490b94ba42SJung-uk Kim 500b94ba42SJung-uk Kim #define _COMPONENT ACPI_COMPILER 510b94ba42SJung-uk Kim ACPI_MODULE_NAME ("aslwalks") 520b94ba42SJung-uk Kim 530b94ba42SJung-uk Kim 54f8146b88SJung-uk Kim /* Local prototypes */ 55f8146b88SJung-uk Kim 56f8146b88SJung-uk Kim static void 57f8146b88SJung-uk Kim AnAnalyzeStoreOperator ( 58f8146b88SJung-uk Kim ACPI_PARSE_OBJECT *Op); 59f8146b88SJung-uk Kim 60f8146b88SJung-uk Kim 610b94ba42SJung-uk Kim /******************************************************************************* 620b94ba42SJung-uk Kim * 630b94ba42SJung-uk Kim * FUNCTION: AnMethodTypingWalkEnd 640b94ba42SJung-uk Kim * 650b94ba42SJung-uk Kim * PARAMETERS: ASL_WALK_CALLBACK 660b94ba42SJung-uk Kim * 670b94ba42SJung-uk Kim * RETURN: Status 680b94ba42SJung-uk Kim * 690b94ba42SJung-uk Kim * DESCRIPTION: Ascending callback for typing walk. Complete the method 700b94ba42SJung-uk Kim * return analysis. Check methods for: 710b94ba42SJung-uk Kim * 1) Initialized local variables 720b94ba42SJung-uk Kim * 2) Valid arguments 730b94ba42SJung-uk Kim * 3) Return types 740b94ba42SJung-uk Kim * 750b94ba42SJung-uk Kim ******************************************************************************/ 760b94ba42SJung-uk Kim 770b94ba42SJung-uk Kim ACPI_STATUS 780b94ba42SJung-uk Kim AnMethodTypingWalkEnd ( 790b94ba42SJung-uk Kim ACPI_PARSE_OBJECT *Op, 800b94ba42SJung-uk Kim UINT32 Level, 810b94ba42SJung-uk Kim void *Context) 820b94ba42SJung-uk Kim { 83f8146b88SJung-uk Kim UINT32 ThisOpBtype; 840b94ba42SJung-uk Kim 850b94ba42SJung-uk Kim 860b94ba42SJung-uk Kim switch (Op->Asl.ParseOpcode) 870b94ba42SJung-uk Kim { 880b94ba42SJung-uk Kim case PARSEOP_METHOD: 890b94ba42SJung-uk Kim 900b94ba42SJung-uk Kim Op->Asl.CompileFlags |= NODE_METHOD_TYPED; 910b94ba42SJung-uk Kim break; 920b94ba42SJung-uk Kim 930b94ba42SJung-uk Kim case PARSEOP_RETURN: 940b94ba42SJung-uk Kim 950b94ba42SJung-uk Kim if ((Op->Asl.Child) && 960b94ba42SJung-uk Kim (Op->Asl.Child->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG)) 970b94ba42SJung-uk Kim { 98f8146b88SJung-uk Kim ThisOpBtype = AnGetBtype (Op->Asl.Child); 990b94ba42SJung-uk Kim 1000b94ba42SJung-uk Kim if ((Op->Asl.Child->Asl.ParseOpcode == PARSEOP_METHODCALL) && 101f8146b88SJung-uk Kim (ThisOpBtype == (ACPI_UINT32_MAX -1))) 1020b94ba42SJung-uk Kim { 1030b94ba42SJung-uk Kim /* 1040b94ba42SJung-uk Kim * The called method is untyped at this time (typically a 1050b94ba42SJung-uk Kim * forward reference). 1060b94ba42SJung-uk Kim * 107f8146b88SJung-uk Kim * Check for a recursive method call first. Note: the 108f8146b88SJung-uk Kim * Child->Node will be null if the method has not been 109f8146b88SJung-uk Kim * resolved. 1100b94ba42SJung-uk Kim */ 111f8146b88SJung-uk Kim if (Op->Asl.Child->Asl.Node && 112f8146b88SJung-uk Kim (Op->Asl.ParentMethod != Op->Asl.Child->Asl.Node->Op)) 1130b94ba42SJung-uk Kim { 1140b94ba42SJung-uk Kim /* We must type the method here */ 1150b94ba42SJung-uk Kim 1160b94ba42SJung-uk Kim TrWalkParseTree (Op->Asl.Child->Asl.Node->Op, 1170b94ba42SJung-uk Kim ASL_WALK_VISIT_UPWARD, NULL, 1180b94ba42SJung-uk Kim AnMethodTypingWalkEnd, NULL); 1190b94ba42SJung-uk Kim 120f8146b88SJung-uk Kim ThisOpBtype = AnGetBtype (Op->Asl.Child); 1210b94ba42SJung-uk Kim } 1220b94ba42SJung-uk Kim } 1230b94ba42SJung-uk Kim 1240b94ba42SJung-uk Kim /* Returns a value, save the value type */ 1250b94ba42SJung-uk Kim 1260b94ba42SJung-uk Kim if (Op->Asl.ParentMethod) 1270b94ba42SJung-uk Kim { 128f8146b88SJung-uk Kim Op->Asl.ParentMethod->Asl.AcpiBtype |= ThisOpBtype; 1290b94ba42SJung-uk Kim } 1300b94ba42SJung-uk Kim } 1310b94ba42SJung-uk Kim break; 1320b94ba42SJung-uk Kim 1330b94ba42SJung-uk Kim default: 134a9d8d09cSJung-uk Kim 1350b94ba42SJung-uk Kim break; 1360b94ba42SJung-uk Kim } 1370b94ba42SJung-uk Kim 1380b94ba42SJung-uk Kim return (AE_OK); 1390b94ba42SJung-uk Kim } 1400b94ba42SJung-uk Kim 1410b94ba42SJung-uk Kim 1420b94ba42SJung-uk Kim /******************************************************************************* 1430b94ba42SJung-uk Kim * 1440b94ba42SJung-uk Kim * FUNCTION: AnOperandTypecheckWalkEnd 1450b94ba42SJung-uk Kim * 1460b94ba42SJung-uk Kim * PARAMETERS: ASL_WALK_CALLBACK 1470b94ba42SJung-uk Kim * 1480b94ba42SJung-uk Kim * RETURN: Status 1490b94ba42SJung-uk Kim * 1500b94ba42SJung-uk Kim * DESCRIPTION: Ascending callback for analysis walk. Complete method 1510b94ba42SJung-uk Kim * return analysis. 1520b94ba42SJung-uk Kim * 1530b94ba42SJung-uk Kim ******************************************************************************/ 1540b94ba42SJung-uk Kim 1550b94ba42SJung-uk Kim ACPI_STATUS 1560b94ba42SJung-uk Kim AnOperandTypecheckWalkEnd ( 1570b94ba42SJung-uk Kim ACPI_PARSE_OBJECT *Op, 1580b94ba42SJung-uk Kim UINT32 Level, 1590b94ba42SJung-uk Kim void *Context) 1600b94ba42SJung-uk Kim { 1610b94ba42SJung-uk Kim const ACPI_OPCODE_INFO *OpInfo; 1620b94ba42SJung-uk Kim UINT32 RuntimeArgTypes; 1630b94ba42SJung-uk Kim UINT32 RuntimeArgTypes2; 1640b94ba42SJung-uk Kim UINT32 RequiredBtypes; 1650b94ba42SJung-uk Kim UINT32 ThisNodeBtype; 1660b94ba42SJung-uk Kim UINT32 CommonBtypes; 1670b94ba42SJung-uk Kim UINT32 OpcodeClass; 1680b94ba42SJung-uk Kim ACPI_PARSE_OBJECT *ArgOp; 1690b94ba42SJung-uk Kim UINT32 ArgType; 1700b94ba42SJung-uk Kim 1710b94ba42SJung-uk Kim 1720b94ba42SJung-uk Kim switch (Op->Asl.AmlOpcode) 1730b94ba42SJung-uk Kim { 1740b94ba42SJung-uk Kim case AML_RAW_DATA_BYTE: 1750b94ba42SJung-uk Kim case AML_RAW_DATA_WORD: 1760b94ba42SJung-uk Kim case AML_RAW_DATA_DWORD: 1770b94ba42SJung-uk Kim case AML_RAW_DATA_QWORD: 1780b94ba42SJung-uk Kim case AML_RAW_DATA_BUFFER: 1790b94ba42SJung-uk Kim case AML_RAW_DATA_CHAIN: 1800b94ba42SJung-uk Kim case AML_PACKAGE_LENGTH: 1810b94ba42SJung-uk Kim case AML_UNASSIGNED_OPCODE: 1820b94ba42SJung-uk Kim case AML_DEFAULT_ARG_OP: 1830b94ba42SJung-uk Kim 1840b94ba42SJung-uk Kim /* Ignore the internal (compiler-only) AML opcodes */ 1850b94ba42SJung-uk Kim 1860b94ba42SJung-uk Kim return (AE_OK); 1870b94ba42SJung-uk Kim 1880b94ba42SJung-uk Kim default: 189a9d8d09cSJung-uk Kim 1900b94ba42SJung-uk Kim break; 1910b94ba42SJung-uk Kim } 1920b94ba42SJung-uk Kim 1930b94ba42SJung-uk Kim OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode); 1940b94ba42SJung-uk Kim if (!OpInfo) 1950b94ba42SJung-uk Kim { 1960b94ba42SJung-uk Kim return (AE_OK); 1970b94ba42SJung-uk Kim } 1980b94ba42SJung-uk Kim 1990b94ba42SJung-uk Kim ArgOp = Op->Asl.Child; 2000b94ba42SJung-uk Kim OpcodeClass = OpInfo->Class; 201f8146b88SJung-uk Kim RuntimeArgTypes = OpInfo->RuntimeArgs; 2020b94ba42SJung-uk Kim 2030b94ba42SJung-uk Kim #ifdef ASL_ERROR_NAMED_OBJECT_IN_WHILE 2040b94ba42SJung-uk Kim /* 2050b94ba42SJung-uk Kim * Update 11/2008: In practice, we can't perform this check. A simple 2060b94ba42SJung-uk Kim * analysis is not sufficient. Also, it can cause errors when compiling 2070b94ba42SJung-uk Kim * disassembled code because of the way Switch operators are implemented 2080b94ba42SJung-uk Kim * (a While(One) loop with a named temp variable created within.) 2090b94ba42SJung-uk Kim */ 2100b94ba42SJung-uk Kim 2110b94ba42SJung-uk Kim /* 2120b94ba42SJung-uk Kim * If we are creating a named object, check if we are within a while loop 2130b94ba42SJung-uk Kim * by checking if the parent is a WHILE op. This is a simple analysis, but 2140b94ba42SJung-uk Kim * probably sufficient for many cases. 2150b94ba42SJung-uk Kim * 2160b94ba42SJung-uk Kim * Allow Scope(), Buffer(), and Package(). 2170b94ba42SJung-uk Kim */ 2180b94ba42SJung-uk Kim if (((OpcodeClass == AML_CLASS_NAMED_OBJECT) && (Op->Asl.AmlOpcode != AML_SCOPE_OP)) || 2190b94ba42SJung-uk Kim ((OpcodeClass == AML_CLASS_CREATE) && (OpInfo->Flags & AML_NSNODE))) 2200b94ba42SJung-uk Kim { 2210b94ba42SJung-uk Kim if (Op->Asl.Parent->Asl.AmlOpcode == AML_WHILE_OP) 2220b94ba42SJung-uk Kim { 2230b94ba42SJung-uk Kim AslError (ASL_ERROR, ASL_MSG_NAMED_OBJECT_IN_WHILE, Op, NULL); 2240b94ba42SJung-uk Kim } 2250b94ba42SJung-uk Kim } 2260b94ba42SJung-uk Kim #endif 2270b94ba42SJung-uk Kim 2280b94ba42SJung-uk Kim /* 2290b94ba42SJung-uk Kim * Special case for control opcodes IF/RETURN/WHILE since they 2300b94ba42SJung-uk Kim * have no runtime arg list (at this time) 2310b94ba42SJung-uk Kim */ 2320b94ba42SJung-uk Kim switch (Op->Asl.AmlOpcode) 2330b94ba42SJung-uk Kim { 2340b94ba42SJung-uk Kim case AML_IF_OP: 2350b94ba42SJung-uk Kim case AML_WHILE_OP: 2360b94ba42SJung-uk Kim case AML_RETURN_OP: 2370b94ba42SJung-uk Kim 2380b94ba42SJung-uk Kim if (ArgOp->Asl.ParseOpcode == PARSEOP_METHODCALL) 2390b94ba42SJung-uk Kim { 2400b94ba42SJung-uk Kim /* Check for an internal method */ 2410b94ba42SJung-uk Kim 2420b94ba42SJung-uk Kim if (AnIsInternalMethod (ArgOp)) 2430b94ba42SJung-uk Kim { 2440b94ba42SJung-uk Kim return (AE_OK); 2450b94ba42SJung-uk Kim } 2460b94ba42SJung-uk Kim 2470b94ba42SJung-uk Kim /* The lone arg is a method call, check it */ 2480b94ba42SJung-uk Kim 2490b94ba42SJung-uk Kim RequiredBtypes = AnMapArgTypeToBtype (ARGI_INTEGER); 2500b94ba42SJung-uk Kim if (Op->Asl.AmlOpcode == AML_RETURN_OP) 2510b94ba42SJung-uk Kim { 2520b94ba42SJung-uk Kim RequiredBtypes = 0xFFFFFFFF; 2530b94ba42SJung-uk Kim } 2540b94ba42SJung-uk Kim 2550b94ba42SJung-uk Kim ThisNodeBtype = AnGetBtype (ArgOp); 2560b94ba42SJung-uk Kim if (ThisNodeBtype == ACPI_UINT32_MAX) 2570b94ba42SJung-uk Kim { 2580b94ba42SJung-uk Kim return (AE_OK); 2590b94ba42SJung-uk Kim } 260f8146b88SJung-uk Kim 2610b94ba42SJung-uk Kim AnCheckMethodReturnValue (Op, OpInfo, ArgOp, 2620b94ba42SJung-uk Kim RequiredBtypes, ThisNodeBtype); 2630b94ba42SJung-uk Kim } 2640b94ba42SJung-uk Kim return (AE_OK); 2650b94ba42SJung-uk Kim 2667cf3e94aSJung-uk Kim case AML_EXTERNAL_OP: 2677cf3e94aSJung-uk Kim /* 2687cf3e94aSJung-uk Kim * Not really a "runtime" opcode since it used by disassembler only. 2697cf3e94aSJung-uk Kim * The parser will find any issues with the operands. 2707cf3e94aSJung-uk Kim */ 2717cf3e94aSJung-uk Kim return (AE_OK); 2727cf3e94aSJung-uk Kim 2730b94ba42SJung-uk Kim default: 274a9d8d09cSJung-uk Kim 2750b94ba42SJung-uk Kim break; 2760b94ba42SJung-uk Kim } 2770b94ba42SJung-uk Kim 2780b94ba42SJung-uk Kim /* Ignore the non-executable opcodes */ 2790b94ba42SJung-uk Kim 2800b94ba42SJung-uk Kim if (RuntimeArgTypes == ARGI_INVALID_OPCODE) 2810b94ba42SJung-uk Kim { 2820b94ba42SJung-uk Kim return (AE_OK); 2830b94ba42SJung-uk Kim } 2840b94ba42SJung-uk Kim 285f8146b88SJung-uk Kim /* 286f8146b88SJung-uk Kim * Special handling for certain opcodes. 287f8146b88SJung-uk Kim */ 288f8146b88SJung-uk Kim switch (Op->Asl.AmlOpcode) 289f8146b88SJung-uk Kim { 290f8146b88SJung-uk Kim /* BankField has one TermArg */ 291f8146b88SJung-uk Kim 292f8146b88SJung-uk Kim case AML_BANK_FIELD_OP: 293f8146b88SJung-uk Kim 294f8146b88SJung-uk Kim OpcodeClass = AML_CLASS_EXECUTE; 295f8146b88SJung-uk Kim ArgOp = ArgOp->Asl.Next; 296f8146b88SJung-uk Kim ArgOp = ArgOp->Asl.Next; 297f8146b88SJung-uk Kim break; 298f8146b88SJung-uk Kim 299f8146b88SJung-uk Kim /* Operation Region has 2 TermArgs */ 300f8146b88SJung-uk Kim 301f8146b88SJung-uk Kim case AML_REGION_OP: 302f8146b88SJung-uk Kim 303f8146b88SJung-uk Kim OpcodeClass = AML_CLASS_EXECUTE; 304f8146b88SJung-uk Kim ArgOp = ArgOp->Asl.Next; 305f8146b88SJung-uk Kim ArgOp = ArgOp->Asl.Next; 306f8146b88SJung-uk Kim break; 307f8146b88SJung-uk Kim 308f8146b88SJung-uk Kim /* DataTableRegion has 3 TermArgs */ 309f8146b88SJung-uk Kim 310f8146b88SJung-uk Kim case AML_DATA_REGION_OP: 311f8146b88SJung-uk Kim 312f8146b88SJung-uk Kim OpcodeClass = AML_CLASS_EXECUTE; 313f8146b88SJung-uk Kim ArgOp = ArgOp->Asl.Next; 314f8146b88SJung-uk Kim break; 315f8146b88SJung-uk Kim 316f8146b88SJung-uk Kim /* Buffers/Packages have a length that is a TermArg */ 317f8146b88SJung-uk Kim 318f8146b88SJung-uk Kim case AML_BUFFER_OP: 319f8146b88SJung-uk Kim case AML_PACKAGE_OP: 320f8146b88SJung-uk Kim case AML_VAR_PACKAGE_OP: 321f8146b88SJung-uk Kim 322f8146b88SJung-uk Kim /* If length is a constant, we are done */ 323f8146b88SJung-uk Kim 324f8146b88SJung-uk Kim if ((ArgOp->Asl.ParseOpcode == PARSEOP_INTEGER) || 325f8146b88SJung-uk Kim (ArgOp->Asl.ParseOpcode == PARSEOP_RAW_DATA)) 326f8146b88SJung-uk Kim { 327f8146b88SJung-uk Kim return (AE_OK); 328f8146b88SJung-uk Kim } 329f8146b88SJung-uk Kim break; 330f8146b88SJung-uk Kim 331f8146b88SJung-uk Kim /* Store can write any object to the Debug object */ 332f8146b88SJung-uk Kim 333f8146b88SJung-uk Kim case AML_STORE_OP: 334f8146b88SJung-uk Kim /* 335f8146b88SJung-uk Kim * If this is a Store() to the Debug object, we don't need 336f8146b88SJung-uk Kim * to perform any further validation -- because a Store of 337f8146b88SJung-uk Kim * any object to Debug is permitted and supported. 338f8146b88SJung-uk Kim */ 339f8146b88SJung-uk Kim if (ArgOp->Asl.Next->Asl.AmlOpcode == AML_DEBUG_OP) 340f8146b88SJung-uk Kim { 341f8146b88SJung-uk Kim return (AE_OK); 342f8146b88SJung-uk Kim } 343f8146b88SJung-uk Kim break; 344f8146b88SJung-uk Kim 345f8146b88SJung-uk Kim default: 346f8146b88SJung-uk Kim break; 347f8146b88SJung-uk Kim } 348f8146b88SJung-uk Kim 3490b94ba42SJung-uk Kim switch (OpcodeClass) 3500b94ba42SJung-uk Kim { 3510b94ba42SJung-uk Kim case AML_CLASS_EXECUTE: 3520b94ba42SJung-uk Kim case AML_CLASS_CREATE: 3530b94ba42SJung-uk Kim case AML_CLASS_CONTROL: 3540b94ba42SJung-uk Kim case AML_CLASS_RETURN_VALUE: 3550b94ba42SJung-uk Kim 3560b94ba42SJung-uk Kim /* Reverse the runtime argument list */ 3570b94ba42SJung-uk Kim 3580b94ba42SJung-uk Kim RuntimeArgTypes2 = 0; 3590b94ba42SJung-uk Kim while ((ArgType = GET_CURRENT_ARG_TYPE (RuntimeArgTypes))) 3600b94ba42SJung-uk Kim { 3610b94ba42SJung-uk Kim RuntimeArgTypes2 <<= ARG_TYPE_WIDTH; 3620b94ba42SJung-uk Kim RuntimeArgTypes2 |= ArgType; 3630b94ba42SJung-uk Kim INCREMENT_ARG_LIST (RuntimeArgTypes); 3640b94ba42SJung-uk Kim } 3650b94ba42SJung-uk Kim 366f8146b88SJung-uk Kim /* Typecheck each argument */ 367f8146b88SJung-uk Kim 3680b94ba42SJung-uk Kim while ((ArgType = GET_CURRENT_ARG_TYPE (RuntimeArgTypes2))) 3690b94ba42SJung-uk Kim { 370f8146b88SJung-uk Kim /* Get the required type(s) for the argument */ 371f8146b88SJung-uk Kim 3720b94ba42SJung-uk Kim RequiredBtypes = AnMapArgTypeToBtype (ArgType); 3730b94ba42SJung-uk Kim 3741c0e1b6dSJung-uk Kim if (!ArgOp) 3751c0e1b6dSJung-uk Kim { 3761c0e1b6dSJung-uk Kim AslError (ASL_ERROR, ASL_MSG_COMPILER_INTERNAL, Op, 3771c0e1b6dSJung-uk Kim "Null ArgOp in argument loop"); 3781c0e1b6dSJung-uk Kim AslAbort (); 3791c0e1b6dSJung-uk Kim } 3801c0e1b6dSJung-uk Kim 381f8146b88SJung-uk Kim /* Get the actual type of the argument */ 382f8146b88SJung-uk Kim 3830b94ba42SJung-uk Kim ThisNodeBtype = AnGetBtype (ArgOp); 3840b94ba42SJung-uk Kim if (ThisNodeBtype == ACPI_UINT32_MAX) 3850b94ba42SJung-uk Kim { 3860b94ba42SJung-uk Kim goto NextArgument; 3870b94ba42SJung-uk Kim } 3880b94ba42SJung-uk Kim 3890b94ba42SJung-uk Kim /* Examine the arg based on the required type of the arg */ 3900b94ba42SJung-uk Kim 3910b94ba42SJung-uk Kim switch (ArgType) 3920b94ba42SJung-uk Kim { 3930b94ba42SJung-uk Kim case ARGI_TARGETREF: 3940b94ba42SJung-uk Kim 3950b94ba42SJung-uk Kim if (ArgOp->Asl.ParseOpcode == PARSEOP_ZERO) 3960b94ba42SJung-uk Kim { 3970b94ba42SJung-uk Kim /* ZERO is the placeholder for "don't store result" */ 3980b94ba42SJung-uk Kim 3990b94ba42SJung-uk Kim ThisNodeBtype = RequiredBtypes; 4000b94ba42SJung-uk Kim break; 4010b94ba42SJung-uk Kim } 4020b94ba42SJung-uk Kim 403f8146b88SJung-uk Kim /* Fallthrough */ 404f8146b88SJung-uk Kim 405f8146b88SJung-uk Kim case ARGI_STORE_TARGET: 406f8146b88SJung-uk Kim 4070b94ba42SJung-uk Kim if (ArgOp->Asl.ParseOpcode == PARSEOP_INTEGER) 4080b94ba42SJung-uk Kim { 4090b94ba42SJung-uk Kim /* 4100b94ba42SJung-uk Kim * This is the case where an original reference to a resource 4110b94ba42SJung-uk Kim * descriptor field has been replaced by an (Integer) offset. 4120b94ba42SJung-uk Kim * These named fields are supported at compile-time only; 4130b94ba42SJung-uk Kim * the names are not passed to the interpreter (via the AML). 4140b94ba42SJung-uk Kim */ 4150b94ba42SJung-uk Kim if ((ArgOp->Asl.Node->Type == ACPI_TYPE_LOCAL_RESOURCE_FIELD) || 4160b94ba42SJung-uk Kim (ArgOp->Asl.Node->Type == ACPI_TYPE_LOCAL_RESOURCE)) 4170b94ba42SJung-uk Kim { 418f8146b88SJung-uk Kim AslError (ASL_ERROR, ASL_MSG_RESOURCE_FIELD, 419f8146b88SJung-uk Kim ArgOp, NULL); 4200b94ba42SJung-uk Kim } 4210b94ba42SJung-uk Kim else 4220b94ba42SJung-uk Kim { 423f8146b88SJung-uk Kim AslError (ASL_ERROR, ASL_MSG_INVALID_TYPE, 424f8146b88SJung-uk Kim ArgOp, NULL); 425f8146b88SJung-uk Kim } 4260b94ba42SJung-uk Kim } 4270b94ba42SJung-uk Kim break; 4280b94ba42SJung-uk Kim 4290b94ba42SJung-uk Kim 430f8146b88SJung-uk Kim #ifdef __FUTURE_IMPLEMENTATION 431f8146b88SJung-uk Kim /* 432f8146b88SJung-uk Kim * Possible future typechecking support 433f8146b88SJung-uk Kim */ 4340b94ba42SJung-uk Kim case ARGI_REFERENCE: /* References */ 4350b94ba42SJung-uk Kim case ARGI_INTEGER_REF: 4360b94ba42SJung-uk Kim case ARGI_OBJECT_REF: 4370b94ba42SJung-uk Kim case ARGI_DEVICE_REF: 4380b94ba42SJung-uk Kim 4390b94ba42SJung-uk Kim switch (ArgOp->Asl.ParseOpcode) 4400b94ba42SJung-uk Kim { 4410b94ba42SJung-uk Kim case PARSEOP_LOCAL0: 4420b94ba42SJung-uk Kim case PARSEOP_LOCAL1: 4430b94ba42SJung-uk Kim case PARSEOP_LOCAL2: 4440b94ba42SJung-uk Kim case PARSEOP_LOCAL3: 4450b94ba42SJung-uk Kim case PARSEOP_LOCAL4: 4460b94ba42SJung-uk Kim case PARSEOP_LOCAL5: 4470b94ba42SJung-uk Kim case PARSEOP_LOCAL6: 4480b94ba42SJung-uk Kim case PARSEOP_LOCAL7: 4490b94ba42SJung-uk Kim 4500b94ba42SJung-uk Kim /* TBD: implement analysis of current value (type) of the local */ 4510b94ba42SJung-uk Kim /* For now, just treat any local as a typematch */ 4520b94ba42SJung-uk Kim 4530b94ba42SJung-uk Kim /*ThisNodeBtype = RequiredBtypes;*/ 4540b94ba42SJung-uk Kim break; 4550b94ba42SJung-uk Kim 4560b94ba42SJung-uk Kim case PARSEOP_ARG0: 4570b94ba42SJung-uk Kim case PARSEOP_ARG1: 4580b94ba42SJung-uk Kim case PARSEOP_ARG2: 4590b94ba42SJung-uk Kim case PARSEOP_ARG3: 4600b94ba42SJung-uk Kim case PARSEOP_ARG4: 4610b94ba42SJung-uk Kim case PARSEOP_ARG5: 4620b94ba42SJung-uk Kim case PARSEOP_ARG6: 4630b94ba42SJung-uk Kim 464f8146b88SJung-uk Kim /* Hard to analyze argument types, so we won't */ 465f8146b88SJung-uk Kim /* for now. Just treat any arg as a typematch */ 4660b94ba42SJung-uk Kim 4670b94ba42SJung-uk Kim /* ThisNodeBtype = RequiredBtypes; */ 4680b94ba42SJung-uk Kim break; 4690b94ba42SJung-uk Kim 4700b94ba42SJung-uk Kim case PARSEOP_DEBUG: 4710b94ba42SJung-uk Kim case PARSEOP_REFOF: 4720b94ba42SJung-uk Kim case PARSEOP_INDEX: 4730b94ba42SJung-uk Kim default: 474a9d8d09cSJung-uk Kim 4750b94ba42SJung-uk Kim break; 4760b94ba42SJung-uk Kim } 4770b94ba42SJung-uk Kim break; 478f8146b88SJung-uk Kim #endif 4790b94ba42SJung-uk Kim case ARGI_INTEGER: 4800b94ba42SJung-uk Kim default: 481a9d8d09cSJung-uk Kim 4820b94ba42SJung-uk Kim break; 4830b94ba42SJung-uk Kim } 4840b94ba42SJung-uk Kim 4850b94ba42SJung-uk Kim 486f8146b88SJung-uk Kim /* Check for a type mismatch (required versus actual) */ 487f8146b88SJung-uk Kim 4880b94ba42SJung-uk Kim CommonBtypes = ThisNodeBtype & RequiredBtypes; 4890b94ba42SJung-uk Kim 4900b94ba42SJung-uk Kim if (ArgOp->Asl.ParseOpcode == PARSEOP_METHODCALL) 4910b94ba42SJung-uk Kim { 4920b94ba42SJung-uk Kim if (AnIsInternalMethod (ArgOp)) 4930b94ba42SJung-uk Kim { 4940b94ba42SJung-uk Kim return (AE_OK); 4950b94ba42SJung-uk Kim } 4960b94ba42SJung-uk Kim 4970b94ba42SJung-uk Kim /* Check a method call for a valid return value */ 4980b94ba42SJung-uk Kim 4990b94ba42SJung-uk Kim AnCheckMethodReturnValue (Op, OpInfo, ArgOp, 5000b94ba42SJung-uk Kim RequiredBtypes, ThisNodeBtype); 5010b94ba42SJung-uk Kim } 5020b94ba42SJung-uk Kim 5030b94ba42SJung-uk Kim /* 5040b94ba42SJung-uk Kim * Now check if the actual type(s) match at least one 5050b94ba42SJung-uk Kim * bit to the required type 5060b94ba42SJung-uk Kim */ 5070b94ba42SJung-uk Kim else if (!CommonBtypes) 5080b94ba42SJung-uk Kim { 5090b94ba42SJung-uk Kim /* No match -- this is a type mismatch error */ 5100b94ba42SJung-uk Kim 5110b94ba42SJung-uk Kim AnFormatBtype (StringBuffer, ThisNodeBtype); 5120b94ba42SJung-uk Kim AnFormatBtype (StringBuffer2, RequiredBtypes); 5130b94ba42SJung-uk Kim 5140b94ba42SJung-uk Kim sprintf (MsgBuffer, "[%s] found, %s operator requires [%s]", 5150b94ba42SJung-uk Kim StringBuffer, OpInfo->Name, StringBuffer2); 5160b94ba42SJung-uk Kim 517f8146b88SJung-uk Kim AslError (ASL_ERROR, ASL_MSG_INVALID_TYPE, 518f8146b88SJung-uk Kim ArgOp, MsgBuffer); 5190b94ba42SJung-uk Kim } 5200b94ba42SJung-uk Kim 5210b94ba42SJung-uk Kim NextArgument: 5220b94ba42SJung-uk Kim ArgOp = ArgOp->Asl.Next; 5230b94ba42SJung-uk Kim INCREMENT_ARG_LIST (RuntimeArgTypes2); 5240b94ba42SJung-uk Kim } 5250b94ba42SJung-uk Kim break; 5260b94ba42SJung-uk Kim 5270b94ba42SJung-uk Kim default: 528a9d8d09cSJung-uk Kim 5290b94ba42SJung-uk Kim break; 5300b94ba42SJung-uk Kim } 5310b94ba42SJung-uk Kim 5320b94ba42SJung-uk Kim return (AE_OK); 5330b94ba42SJung-uk Kim } 5340b94ba42SJung-uk Kim 5350b94ba42SJung-uk Kim 5360b94ba42SJung-uk Kim /******************************************************************************* 5370b94ba42SJung-uk Kim * 5380b94ba42SJung-uk Kim * FUNCTION: AnOtherSemanticAnalysisWalkBegin 5390b94ba42SJung-uk Kim * 5400b94ba42SJung-uk Kim * PARAMETERS: ASL_WALK_CALLBACK 5410b94ba42SJung-uk Kim * 5420b94ba42SJung-uk Kim * RETURN: Status 5430b94ba42SJung-uk Kim * 5440b94ba42SJung-uk Kim * DESCRIPTION: Descending callback for the analysis walk. Checks for 5450b94ba42SJung-uk Kim * miscellaneous issues in the code. 5460b94ba42SJung-uk Kim * 5470b94ba42SJung-uk Kim ******************************************************************************/ 5480b94ba42SJung-uk Kim 5490b94ba42SJung-uk Kim ACPI_STATUS 5500b94ba42SJung-uk Kim AnOtherSemanticAnalysisWalkBegin ( 5510b94ba42SJung-uk Kim ACPI_PARSE_OBJECT *Op, 5520b94ba42SJung-uk Kim UINT32 Level, 5530b94ba42SJung-uk Kim void *Context) 5540b94ba42SJung-uk Kim { 555f8146b88SJung-uk Kim ACPI_PARSE_OBJECT *ArgOp; 556f8146b88SJung-uk Kim ACPI_PARSE_OBJECT *PrevArgOp = NULL; 5570b94ba42SJung-uk Kim const ACPI_OPCODE_INFO *OpInfo; 5583f0275a0SJung-uk Kim ACPI_NAMESPACE_NODE *Node; 5590b94ba42SJung-uk Kim 5600b94ba42SJung-uk Kim 5610b94ba42SJung-uk Kim OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode); 5620b94ba42SJung-uk Kim 563f8146b88SJung-uk Kim 5640b94ba42SJung-uk Kim /* 5650b94ba42SJung-uk Kim * Determine if an execution class operator actually does something by 5660b94ba42SJung-uk Kim * checking if it has a target and/or the function return value is used. 5670b94ba42SJung-uk Kim * (Target is optional, so a standalone statement can actually do nothing.) 5680b94ba42SJung-uk Kim */ 5690b94ba42SJung-uk Kim if ((OpInfo->Class == AML_CLASS_EXECUTE) && 5700b94ba42SJung-uk Kim (OpInfo->Flags & AML_HAS_RETVAL) && 5710b94ba42SJung-uk Kim (!AnIsResultUsed (Op))) 5720b94ba42SJung-uk Kim { 5730b94ba42SJung-uk Kim if (OpInfo->Flags & AML_HAS_TARGET) 5740b94ba42SJung-uk Kim { 5750b94ba42SJung-uk Kim /* 576f8146b88SJung-uk Kim * Find the target node, it is always the last child. If the target 5770b94ba42SJung-uk Kim * is not specified in the ASL, a default node of type Zero was 5780b94ba42SJung-uk Kim * created by the parser. 5790b94ba42SJung-uk Kim */ 580f8146b88SJung-uk Kim ArgOp = Op->Asl.Child; 581f8146b88SJung-uk Kim while (ArgOp->Asl.Next) 5820b94ba42SJung-uk Kim { 583f8146b88SJung-uk Kim PrevArgOp = ArgOp; 584f8146b88SJung-uk Kim ArgOp = ArgOp->Asl.Next; 5850b94ba42SJung-uk Kim } 5860b94ba42SJung-uk Kim 5870b94ba42SJung-uk Kim /* Divide() is the only weird case, it has two targets */ 5880b94ba42SJung-uk Kim 5890b94ba42SJung-uk Kim if (Op->Asl.AmlOpcode == AML_DIVIDE_OP) 5900b94ba42SJung-uk Kim { 591f8146b88SJung-uk Kim if ((ArgOp->Asl.ParseOpcode == PARSEOP_ZERO) && 592f8146b88SJung-uk Kim (PrevArgOp) && 593f8146b88SJung-uk Kim (PrevArgOp->Asl.ParseOpcode == PARSEOP_ZERO)) 5940b94ba42SJung-uk Kim { 5959c7c683cSJung-uk Kim AslError (ASL_ERROR, ASL_MSG_RESULT_NOT_USED, 5960b94ba42SJung-uk Kim Op, Op->Asl.ExternalName); 5970b94ba42SJung-uk Kim } 5980b94ba42SJung-uk Kim } 599f8146b88SJung-uk Kim 600f8146b88SJung-uk Kim else if (ArgOp->Asl.ParseOpcode == PARSEOP_ZERO) 6010b94ba42SJung-uk Kim { 6029c7c683cSJung-uk Kim AslError (ASL_ERROR, ASL_MSG_RESULT_NOT_USED, 6030b94ba42SJung-uk Kim Op, Op->Asl.ExternalName); 6040b94ba42SJung-uk Kim } 6050b94ba42SJung-uk Kim } 6060b94ba42SJung-uk Kim else 6070b94ba42SJung-uk Kim { 6080b94ba42SJung-uk Kim /* 6090b94ba42SJung-uk Kim * Has no target and the result is not used. Only a couple opcodes 6100b94ba42SJung-uk Kim * can have this combination. 6110b94ba42SJung-uk Kim */ 6120b94ba42SJung-uk Kim switch (Op->Asl.ParseOpcode) 6130b94ba42SJung-uk Kim { 6140b94ba42SJung-uk Kim case PARSEOP_ACQUIRE: 6150b94ba42SJung-uk Kim case PARSEOP_WAIT: 6160b94ba42SJung-uk Kim case PARSEOP_LOADTABLE: 617a9d8d09cSJung-uk Kim 6180b94ba42SJung-uk Kim break; 6190b94ba42SJung-uk Kim 6200b94ba42SJung-uk Kim default: 621a9d8d09cSJung-uk Kim 6229c7c683cSJung-uk Kim AslError (ASL_ERROR, ASL_MSG_RESULT_NOT_USED, 6230b94ba42SJung-uk Kim Op, Op->Asl.ExternalName); 6240b94ba42SJung-uk Kim break; 6250b94ba42SJung-uk Kim } 6260b94ba42SJung-uk Kim } 6270b94ba42SJung-uk Kim } 6280b94ba42SJung-uk Kim 6290b94ba42SJung-uk Kim 6300b94ba42SJung-uk Kim /* 6310b94ba42SJung-uk Kim * Semantic checks for individual ASL operators 6320b94ba42SJung-uk Kim */ 6330b94ba42SJung-uk Kim switch (Op->Asl.ParseOpcode) 6340b94ba42SJung-uk Kim { 635f8146b88SJung-uk Kim case PARSEOP_STORE: 636f8146b88SJung-uk Kim 637f8146b88SJung-uk Kim if (Gbl_DoTypechecking) 638f8146b88SJung-uk Kim { 639f8146b88SJung-uk Kim AnAnalyzeStoreOperator (Op); 640f8146b88SJung-uk Kim } 641f8146b88SJung-uk Kim break; 642f8146b88SJung-uk Kim 643f8146b88SJung-uk Kim 6440b94ba42SJung-uk Kim case PARSEOP_ACQUIRE: 6450b94ba42SJung-uk Kim case PARSEOP_WAIT: 6460b94ba42SJung-uk Kim /* 6470b94ba42SJung-uk Kim * Emit a warning if the timeout parameter for these operators is not 6480b94ba42SJung-uk Kim * ACPI_WAIT_FOREVER, and the result value from the operator is not 6490b94ba42SJung-uk Kim * checked, meaning that a timeout could happen, but the code 6500b94ba42SJung-uk Kim * would not know about it. 6510b94ba42SJung-uk Kim */ 6520b94ba42SJung-uk Kim 6530b94ba42SJung-uk Kim /* First child is the namepath, 2nd child is timeout */ 6540b94ba42SJung-uk Kim 655f8146b88SJung-uk Kim ArgOp = Op->Asl.Child; 656f8146b88SJung-uk Kim ArgOp = ArgOp->Asl.Next; 6570b94ba42SJung-uk Kim 6580b94ba42SJung-uk Kim /* 6590b94ba42SJung-uk Kim * Check for the WAIT_FOREVER case - defined by the ACPI spec to be 6600b94ba42SJung-uk Kim * 0xFFFF or greater 6610b94ba42SJung-uk Kim */ 662f8146b88SJung-uk Kim if (((ArgOp->Asl.ParseOpcode == PARSEOP_WORDCONST) || 663f8146b88SJung-uk Kim (ArgOp->Asl.ParseOpcode == PARSEOP_INTEGER)) && 664f8146b88SJung-uk Kim (ArgOp->Asl.Value.Integer >= (UINT64) ACPI_WAIT_FOREVER)) 6650b94ba42SJung-uk Kim { 6660b94ba42SJung-uk Kim break; 6670b94ba42SJung-uk Kim } 6680b94ba42SJung-uk Kim 6690b94ba42SJung-uk Kim /* 6700b94ba42SJung-uk Kim * The operation could timeout. If the return value is not used 6710b94ba42SJung-uk Kim * (indicates timeout occurred), issue a warning 6720b94ba42SJung-uk Kim */ 6730b94ba42SJung-uk Kim if (!AnIsResultUsed (Op)) 6740b94ba42SJung-uk Kim { 675f8146b88SJung-uk Kim AslError (ASL_WARNING, ASL_MSG_TIMEOUT, ArgOp, 6760b94ba42SJung-uk Kim Op->Asl.ExternalName); 6770b94ba42SJung-uk Kim } 6780b94ba42SJung-uk Kim break; 6790b94ba42SJung-uk Kim 6800b94ba42SJung-uk Kim case PARSEOP_CREATEFIELD: 6810b94ba42SJung-uk Kim /* 6820b94ba42SJung-uk Kim * Check for a zero Length (NumBits) operand. NumBits is the 3rd operand 6830b94ba42SJung-uk Kim */ 684f8146b88SJung-uk Kim ArgOp = Op->Asl.Child; 685f8146b88SJung-uk Kim ArgOp = ArgOp->Asl.Next; 686f8146b88SJung-uk Kim ArgOp = ArgOp->Asl.Next; 6870b94ba42SJung-uk Kim 688f8146b88SJung-uk Kim if ((ArgOp->Asl.ParseOpcode == PARSEOP_ZERO) || 689f8146b88SJung-uk Kim ((ArgOp->Asl.ParseOpcode == PARSEOP_INTEGER) && 690f8146b88SJung-uk Kim (ArgOp->Asl.Value.Integer == 0))) 6910b94ba42SJung-uk Kim { 692f8146b88SJung-uk Kim AslError (ASL_ERROR, ASL_MSG_NON_ZERO, ArgOp, NULL); 6930b94ba42SJung-uk Kim } 6940b94ba42SJung-uk Kim break; 6950b94ba42SJung-uk Kim 6963f0275a0SJung-uk Kim case PARSEOP_CONNECTION: 6973f0275a0SJung-uk Kim /* 6983f0275a0SJung-uk Kim * Ensure that the referenced operation region has the correct SPACE_ID. 6993f0275a0SJung-uk Kim * From the grammar/parser, we know the parent is a FIELD definition. 7003f0275a0SJung-uk Kim */ 701f8146b88SJung-uk Kim ArgOp = Op->Asl.Parent; /* Field definition */ 702f8146b88SJung-uk Kim ArgOp = ArgOp->Asl.Child; /* First child is the OpRegion Name */ 703f8146b88SJung-uk Kim Node = ArgOp->Asl.Node; /* OpRegion namespace node */ 704313a0c13SJung-uk Kim if (!Node) 705313a0c13SJung-uk Kim { 706313a0c13SJung-uk Kim break; 707313a0c13SJung-uk Kim } 7083f0275a0SJung-uk Kim 709f8146b88SJung-uk Kim ArgOp = Node->Op; /* OpRegion definition */ 710f8146b88SJung-uk Kim ArgOp = ArgOp->Asl.Child; /* First child is the OpRegion Name */ 711f8146b88SJung-uk Kim ArgOp = ArgOp->Asl.Next; /* Next peer is the SPACE_ID (what we want) */ 7123f0275a0SJung-uk Kim 7133f0275a0SJung-uk Kim /* 7143f0275a0SJung-uk Kim * The Connection() operator is only valid for the following operation 7153f0275a0SJung-uk Kim * region SpaceIds: GeneralPurposeIo and GenericSerialBus. 7163f0275a0SJung-uk Kim */ 717f8146b88SJung-uk Kim if ((ArgOp->Asl.Value.Integer != ACPI_ADR_SPACE_GPIO) && 718f8146b88SJung-uk Kim (ArgOp->Asl.Value.Integer != ACPI_ADR_SPACE_GSBUS)) 7193f0275a0SJung-uk Kim { 7203f0275a0SJung-uk Kim AslError (ASL_ERROR, ASL_MSG_CONNECTION_INVALID, Op, NULL); 7213f0275a0SJung-uk Kim } 7223f0275a0SJung-uk Kim break; 7233f0275a0SJung-uk Kim 7243f0275a0SJung-uk Kim case PARSEOP_FIELD: 7253f0275a0SJung-uk Kim /* 7263f0275a0SJung-uk Kim * Ensure that fields for GeneralPurposeIo and GenericSerialBus 7273f0275a0SJung-uk Kim * contain at least one Connection() operator 7283f0275a0SJung-uk Kim */ 729f8146b88SJung-uk Kim ArgOp = Op->Asl.Child; /* 1st child is the OpRegion Name */ 730f8146b88SJung-uk Kim Node = ArgOp->Asl.Node; /* OpRegion namespace node */ 7313f0275a0SJung-uk Kim if (!Node) 7323f0275a0SJung-uk Kim { 7333f0275a0SJung-uk Kim break; 7343f0275a0SJung-uk Kim } 7353f0275a0SJung-uk Kim 736f8146b88SJung-uk Kim ArgOp = Node->Op; /* OpRegion definition */ 737f8146b88SJung-uk Kim ArgOp = ArgOp->Asl.Child; /* First child is the OpRegion Name */ 738f8146b88SJung-uk Kim ArgOp = ArgOp->Asl.Next; /* Next peer is the SPACE_ID (what we want) */ 7393f0275a0SJung-uk Kim 7403f0275a0SJung-uk Kim /* We are only interested in GeneralPurposeIo and GenericSerialBus */ 7413f0275a0SJung-uk Kim 742f8146b88SJung-uk Kim if ((ArgOp->Asl.Value.Integer != ACPI_ADR_SPACE_GPIO) && 743f8146b88SJung-uk Kim (ArgOp->Asl.Value.Integer != ACPI_ADR_SPACE_GSBUS)) 7443f0275a0SJung-uk Kim { 7453f0275a0SJung-uk Kim break; 7463f0275a0SJung-uk Kim } 7473f0275a0SJung-uk Kim 748f8146b88SJung-uk Kim ArgOp = Op->Asl.Child; /* 1st child is the OpRegion Name */ 749f8146b88SJung-uk Kim ArgOp = ArgOp->Asl.Next; /* AccessType */ 750f8146b88SJung-uk Kim ArgOp = ArgOp->Asl.Next; /* LockRule */ 751f8146b88SJung-uk Kim ArgOp = ArgOp->Asl.Next; /* UpdateRule */ 752f8146b88SJung-uk Kim ArgOp = ArgOp->Asl.Next; /* Start of FieldUnitList */ 7533f0275a0SJung-uk Kim 7543f0275a0SJung-uk Kim /* Walk the FieldUnitList */ 7553f0275a0SJung-uk Kim 756f8146b88SJung-uk Kim while (ArgOp) 7573f0275a0SJung-uk Kim { 758f8146b88SJung-uk Kim if (ArgOp->Asl.ParseOpcode == PARSEOP_CONNECTION) 7593f0275a0SJung-uk Kim { 7603f0275a0SJung-uk Kim break; 7613f0275a0SJung-uk Kim } 762f8146b88SJung-uk Kim else if (ArgOp->Asl.ParseOpcode == PARSEOP_NAMESEG) 7633f0275a0SJung-uk Kim { 764f8146b88SJung-uk Kim AslError (ASL_ERROR, ASL_MSG_CONNECTION_MISSING, ArgOp, NULL); 7653f0275a0SJung-uk Kim break; 7663f0275a0SJung-uk Kim } 7673f0275a0SJung-uk Kim 768f8146b88SJung-uk Kim ArgOp = ArgOp->Asl.Next; 7693f0275a0SJung-uk Kim } 7703f0275a0SJung-uk Kim break; 7713f0275a0SJung-uk Kim 7720b94ba42SJung-uk Kim default: 773a9d8d09cSJung-uk Kim 7740b94ba42SJung-uk Kim break; 7750b94ba42SJung-uk Kim } 7760b94ba42SJung-uk Kim 7770b94ba42SJung-uk Kim return (AE_OK); 7780b94ba42SJung-uk Kim } 779f8146b88SJung-uk Kim 780f8146b88SJung-uk Kim 781f8146b88SJung-uk Kim /******************************************************************************* 782f8146b88SJung-uk Kim * 783f8146b88SJung-uk Kim * FUNCTION: AnAnalyzeStoreOperator 784f8146b88SJung-uk Kim * 785f8146b88SJung-uk Kim * PARAMETERS: Op - Store() operator 786f8146b88SJung-uk Kim * 787f8146b88SJung-uk Kim * RETURN: None 788f8146b88SJung-uk Kim * 789f8146b88SJung-uk Kim * DESCRIPTION: Analyze a store operator. Mostly for stores to/from package 790f8146b88SJung-uk Kim * objects where there are more restrictions than other data 791f8146b88SJung-uk Kim * types. 792f8146b88SJung-uk Kim * 793f8146b88SJung-uk Kim ******************************************************************************/ 794f8146b88SJung-uk Kim 795f8146b88SJung-uk Kim static void 796f8146b88SJung-uk Kim AnAnalyzeStoreOperator ( 797f8146b88SJung-uk Kim ACPI_PARSE_OBJECT *Op) 798f8146b88SJung-uk Kim { 799f8146b88SJung-uk Kim ACPI_NAMESPACE_NODE *SourceNode; 800f8146b88SJung-uk Kim ACPI_NAMESPACE_NODE *TargetNode; 801f8146b88SJung-uk Kim ACPI_PARSE_OBJECT *SourceOperandOp; 802f8146b88SJung-uk Kim ACPI_PARSE_OBJECT *TargetOperandOp; 803f8146b88SJung-uk Kim UINT32 SourceOperandBtype; 804f8146b88SJung-uk Kim UINT32 TargetOperandBtype; 805f8146b88SJung-uk Kim 806f8146b88SJung-uk Kim 807f8146b88SJung-uk Kim /* Extract the two operands for STORE */ 808f8146b88SJung-uk Kim 809f8146b88SJung-uk Kim SourceOperandOp = Op->Asl.Child; 810f8146b88SJung-uk Kim TargetOperandOp = SourceOperandOp->Asl.Next; 811f8146b88SJung-uk Kim 812f8146b88SJung-uk Kim /* 813f8146b88SJung-uk Kim * Ignore these Source operand opcodes, they cannot be typechecked, 814f8146b88SJung-uk Kim * the actual result is unknown here. 815f8146b88SJung-uk Kim */ 816f8146b88SJung-uk Kim switch (SourceOperandOp->Asl.ParseOpcode) 817f8146b88SJung-uk Kim { 818f8146b88SJung-uk Kim /* For these, type of the returned value is unknown at compile time */ 819f8146b88SJung-uk Kim 820f8146b88SJung-uk Kim case PARSEOP_DEREFOF: 821f8146b88SJung-uk Kim case PARSEOP_METHODCALL: 822f8146b88SJung-uk Kim case PARSEOP_STORE: 823f8146b88SJung-uk Kim case PARSEOP_COPYOBJECT: 824f8146b88SJung-uk Kim 825f8146b88SJung-uk Kim return; 826f8146b88SJung-uk Kim 827f8146b88SJung-uk Kim case PARSEOP_INDEX: 828f8146b88SJung-uk Kim case PARSEOP_REFOF: 829f8146b88SJung-uk Kim 830f8146b88SJung-uk Kim if (!Gbl_EnableReferenceTypechecking) 831f8146b88SJung-uk Kim { 832f8146b88SJung-uk Kim return; 833f8146b88SJung-uk Kim } 834f8146b88SJung-uk Kim 835f8146b88SJung-uk Kim /* 836f8146b88SJung-uk Kim * These opcodes always return an object reference, and thus 837f8146b88SJung-uk Kim * the result can only be stored to a Local, Arg, or Debug. 838f8146b88SJung-uk Kim */ 839f8146b88SJung-uk Kim if (TargetOperandOp->Asl.AmlOpcode == AML_DEBUG_OP) 840f8146b88SJung-uk Kim { 841f8146b88SJung-uk Kim return; 842f8146b88SJung-uk Kim } 843f8146b88SJung-uk Kim 844f8146b88SJung-uk Kim if ((TargetOperandOp->Asl.AmlOpcode < AML_LOCAL0) || 845f8146b88SJung-uk Kim (TargetOperandOp->Asl.AmlOpcode > AML_ARG6)) 846f8146b88SJung-uk Kim { 847f8146b88SJung-uk Kim AslError (ASL_ERROR, ASL_MSG_INVALID_TYPE, TargetOperandOp, 848f8146b88SJung-uk Kim "Source [Reference], Target must be [Local/Arg/Debug]"); 849f8146b88SJung-uk Kim } 850f8146b88SJung-uk Kim return; 851f8146b88SJung-uk Kim 852f8146b88SJung-uk Kim default: 853f8146b88SJung-uk Kim break; 854f8146b88SJung-uk Kim } 855f8146b88SJung-uk Kim 856f8146b88SJung-uk Kim /* 857f8146b88SJung-uk Kim * Ignore these Target operand opcodes, they cannot be typechecked 858f8146b88SJung-uk Kim */ 859f8146b88SJung-uk Kim switch (TargetOperandOp->Asl.ParseOpcode) 860f8146b88SJung-uk Kim { 861f8146b88SJung-uk Kim case PARSEOP_DEBUG: 862f8146b88SJung-uk Kim case PARSEOP_DEREFOF: 863f8146b88SJung-uk Kim case PARSEOP_REFOF: 864f8146b88SJung-uk Kim case PARSEOP_INDEX: 8651cc50d6bSJung-uk Kim case PARSEOP_STORE: 866f8146b88SJung-uk Kim 867f8146b88SJung-uk Kim return; 868f8146b88SJung-uk Kim 869f8146b88SJung-uk Kim default: 870f8146b88SJung-uk Kim break; 871f8146b88SJung-uk Kim } 872f8146b88SJung-uk Kim 873f8146b88SJung-uk Kim /* 874f8146b88SJung-uk Kim * Ignore typecheck for External() operands of type "UnknownObj", 875f8146b88SJung-uk Kim * we don't know the actual type (source or target). 876f8146b88SJung-uk Kim */ 877f8146b88SJung-uk Kim SourceNode = SourceOperandOp->Asl.Node; 878f8146b88SJung-uk Kim if (SourceNode && 879f8146b88SJung-uk Kim (SourceNode->Flags & ANOBJ_IS_EXTERNAL) && 880f8146b88SJung-uk Kim (SourceNode->Type == ACPI_TYPE_ANY)) 881f8146b88SJung-uk Kim { 882f8146b88SJung-uk Kim return; 883f8146b88SJung-uk Kim } 884f8146b88SJung-uk Kim 885f8146b88SJung-uk Kim TargetNode = TargetOperandOp->Asl.Node; 886f8146b88SJung-uk Kim if (TargetNode && 887f8146b88SJung-uk Kim (TargetNode->Flags & ANOBJ_IS_EXTERNAL) && 888f8146b88SJung-uk Kim (TargetNode->Type == ACPI_TYPE_ANY)) 889f8146b88SJung-uk Kim { 890f8146b88SJung-uk Kim return; 891f8146b88SJung-uk Kim } 892f8146b88SJung-uk Kim 893f8146b88SJung-uk Kim /* 894f8146b88SJung-uk Kim * A NULL node with a namepath AML opcode indicates non-existent 895f8146b88SJung-uk Kim * name. Just return, the error message is generated elsewhere. 896f8146b88SJung-uk Kim */ 897f8146b88SJung-uk Kim if ((!SourceNode && (SourceOperandOp->Asl.AmlOpcode == AML_INT_NAMEPATH_OP)) || 898f8146b88SJung-uk Kim (!TargetNode && (TargetOperandOp->Asl.AmlOpcode == AML_INT_NAMEPATH_OP))) 899f8146b88SJung-uk Kim { 900f8146b88SJung-uk Kim return; 901f8146b88SJung-uk Kim } 902f8146b88SJung-uk Kim 903f8146b88SJung-uk Kim /* 904f8146b88SJung-uk Kim * Simple check for source same as target via NS node. 905f8146b88SJung-uk Kim * -- Could be expanded to locals and args. 906f8146b88SJung-uk Kim */ 907f8146b88SJung-uk Kim if (SourceNode && TargetNode) 908f8146b88SJung-uk Kim { 909f8146b88SJung-uk Kim if (SourceNode == TargetNode) 910f8146b88SJung-uk Kim { 911f8146b88SJung-uk Kim AslError (ASL_WARNING, ASL_MSG_DUPLICATE_ITEM, 912f8146b88SJung-uk Kim TargetOperandOp, "Source is the same as Target"); 913f8146b88SJung-uk Kim return; 914f8146b88SJung-uk Kim } 915f8146b88SJung-uk Kim } 916f8146b88SJung-uk Kim 917f8146b88SJung-uk Kim /* Ignore typecheck if either source or target is a local or arg */ 918f8146b88SJung-uk Kim 919f8146b88SJung-uk Kim if ((SourceOperandOp->Asl.AmlOpcode >= AML_LOCAL0) && 920f8146b88SJung-uk Kim (SourceOperandOp->Asl.AmlOpcode <= AML_ARG6)) 921f8146b88SJung-uk Kim { 922f8146b88SJung-uk Kim return; /* Cannot type a local/arg at compile time */ 923f8146b88SJung-uk Kim } 924f8146b88SJung-uk Kim 925f8146b88SJung-uk Kim if ((TargetOperandOp->Asl.AmlOpcode >= AML_LOCAL0) && 926f8146b88SJung-uk Kim (TargetOperandOp->Asl.AmlOpcode <= AML_ARG6)) 927f8146b88SJung-uk Kim { 928f8146b88SJung-uk Kim return; /* Cannot type a local/arg at compile time */ 929f8146b88SJung-uk Kim } 930f8146b88SJung-uk Kim 931f8146b88SJung-uk Kim /* 932f8146b88SJung-uk Kim * Package objects are a special case because they cannot by implicitly 933f8146b88SJung-uk Kim * converted to/from anything. Check for these two illegal cases: 934f8146b88SJung-uk Kim * 935f8146b88SJung-uk Kim * Store (non-package, package) 936f8146b88SJung-uk Kim * Store (package, non-package) 937f8146b88SJung-uk Kim */ 938f8146b88SJung-uk Kim SourceOperandBtype = AnGetBtype (SourceOperandOp); 939f8146b88SJung-uk Kim TargetOperandBtype = AnGetBtype (TargetOperandOp); 940f8146b88SJung-uk Kim 941f8146b88SJung-uk Kim /* Check source first for (package, non-package) case */ 942f8146b88SJung-uk Kim 943f8146b88SJung-uk Kim if (SourceOperandBtype & ACPI_BTYPE_PACKAGE) 944f8146b88SJung-uk Kim { 945f8146b88SJung-uk Kim /* If Source is PACKAGE-->Target must be PACKAGE */ 946f8146b88SJung-uk Kim 947f8146b88SJung-uk Kim if (!(TargetOperandBtype & ACPI_BTYPE_PACKAGE)) 948f8146b88SJung-uk Kim { 949f8146b88SJung-uk Kim AslError (ASL_ERROR, ASL_MSG_INVALID_TYPE, TargetOperandOp, 950f8146b88SJung-uk Kim "Source is [Package], Target must be a package also"); 951f8146b88SJung-uk Kim } 952f8146b88SJung-uk Kim } 953f8146b88SJung-uk Kim 954f8146b88SJung-uk Kim /* Else check target for (non-package, package) case */ 955f8146b88SJung-uk Kim 956f8146b88SJung-uk Kim else if (TargetOperandBtype & ACPI_BTYPE_PACKAGE) 957f8146b88SJung-uk Kim { 958f8146b88SJung-uk Kim /* If Target is PACKAGE, Source must be PACKAGE */ 959f8146b88SJung-uk Kim 960f8146b88SJung-uk Kim if (!(SourceOperandBtype & ACPI_BTYPE_PACKAGE)) 961f8146b88SJung-uk Kim { 962f8146b88SJung-uk Kim AslError (ASL_ERROR, ASL_MSG_INVALID_TYPE, SourceOperandOp, 963f8146b88SJung-uk Kim "Target is [Package], Source must be a package also"); 964f8146b88SJung-uk Kim } 965f8146b88SJung-uk Kim } 966f8146b88SJung-uk Kim } 967