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 /* 81c0e1b6dSJung-uk Kim * Copyright (C) 2000 - 2015, 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 540b94ba42SJung-uk Kim /******************************************************************************* 550b94ba42SJung-uk Kim * 560b94ba42SJung-uk Kim * FUNCTION: AnMethodTypingWalkEnd 570b94ba42SJung-uk Kim * 580b94ba42SJung-uk Kim * PARAMETERS: ASL_WALK_CALLBACK 590b94ba42SJung-uk Kim * 600b94ba42SJung-uk Kim * RETURN: Status 610b94ba42SJung-uk Kim * 620b94ba42SJung-uk Kim * DESCRIPTION: Ascending callback for typing walk. Complete the method 630b94ba42SJung-uk Kim * return analysis. Check methods for: 640b94ba42SJung-uk Kim * 1) Initialized local variables 650b94ba42SJung-uk Kim * 2) Valid arguments 660b94ba42SJung-uk Kim * 3) Return types 670b94ba42SJung-uk Kim * 680b94ba42SJung-uk Kim ******************************************************************************/ 690b94ba42SJung-uk Kim 700b94ba42SJung-uk Kim ACPI_STATUS 710b94ba42SJung-uk Kim AnMethodTypingWalkEnd ( 720b94ba42SJung-uk Kim ACPI_PARSE_OBJECT *Op, 730b94ba42SJung-uk Kim UINT32 Level, 740b94ba42SJung-uk Kim void *Context) 750b94ba42SJung-uk Kim { 760b94ba42SJung-uk Kim UINT32 ThisNodeBtype; 770b94ba42SJung-uk Kim 780b94ba42SJung-uk Kim 790b94ba42SJung-uk Kim switch (Op->Asl.ParseOpcode) 800b94ba42SJung-uk Kim { 810b94ba42SJung-uk Kim case PARSEOP_METHOD: 820b94ba42SJung-uk Kim 830b94ba42SJung-uk Kim Op->Asl.CompileFlags |= NODE_METHOD_TYPED; 840b94ba42SJung-uk Kim break; 850b94ba42SJung-uk Kim 860b94ba42SJung-uk Kim case PARSEOP_RETURN: 870b94ba42SJung-uk Kim 880b94ba42SJung-uk Kim if ((Op->Asl.Child) && 890b94ba42SJung-uk Kim (Op->Asl.Child->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG)) 900b94ba42SJung-uk Kim { 910b94ba42SJung-uk Kim ThisNodeBtype = AnGetBtype (Op->Asl.Child); 920b94ba42SJung-uk Kim 930b94ba42SJung-uk Kim if ((Op->Asl.Child->Asl.ParseOpcode == PARSEOP_METHODCALL) && 940b94ba42SJung-uk Kim (ThisNodeBtype == (ACPI_UINT32_MAX -1))) 950b94ba42SJung-uk Kim { 960b94ba42SJung-uk Kim /* 970b94ba42SJung-uk Kim * The called method is untyped at this time (typically a 980b94ba42SJung-uk Kim * forward reference). 990b94ba42SJung-uk Kim * 1000b94ba42SJung-uk Kim * Check for a recursive method call first. 1010b94ba42SJung-uk Kim */ 1020b94ba42SJung-uk Kim if (Op->Asl.ParentMethod != Op->Asl.Child->Asl.Node->Op) 1030b94ba42SJung-uk Kim { 1040b94ba42SJung-uk Kim /* We must type the method here */ 1050b94ba42SJung-uk Kim 1060b94ba42SJung-uk Kim TrWalkParseTree (Op->Asl.Child->Asl.Node->Op, 1070b94ba42SJung-uk Kim ASL_WALK_VISIT_UPWARD, NULL, 1080b94ba42SJung-uk Kim AnMethodTypingWalkEnd, NULL); 1090b94ba42SJung-uk Kim 1100b94ba42SJung-uk Kim ThisNodeBtype = AnGetBtype (Op->Asl.Child); 1110b94ba42SJung-uk Kim } 1120b94ba42SJung-uk Kim } 1130b94ba42SJung-uk Kim 1140b94ba42SJung-uk Kim /* Returns a value, save the value type */ 1150b94ba42SJung-uk Kim 1160b94ba42SJung-uk Kim if (Op->Asl.ParentMethod) 1170b94ba42SJung-uk Kim { 1180b94ba42SJung-uk Kim Op->Asl.ParentMethod->Asl.AcpiBtype |= ThisNodeBtype; 1190b94ba42SJung-uk Kim } 1200b94ba42SJung-uk Kim } 1210b94ba42SJung-uk Kim break; 1220b94ba42SJung-uk Kim 1230b94ba42SJung-uk Kim default: 124a9d8d09cSJung-uk Kim 1250b94ba42SJung-uk Kim break; 1260b94ba42SJung-uk Kim } 1270b94ba42SJung-uk Kim 1280b94ba42SJung-uk Kim return (AE_OK); 1290b94ba42SJung-uk Kim } 1300b94ba42SJung-uk Kim 1310b94ba42SJung-uk Kim 1320b94ba42SJung-uk Kim /******************************************************************************* 1330b94ba42SJung-uk Kim * 1340b94ba42SJung-uk Kim * FUNCTION: AnOperandTypecheckWalkEnd 1350b94ba42SJung-uk Kim * 1360b94ba42SJung-uk Kim * PARAMETERS: ASL_WALK_CALLBACK 1370b94ba42SJung-uk Kim * 1380b94ba42SJung-uk Kim * RETURN: Status 1390b94ba42SJung-uk Kim * 1400b94ba42SJung-uk Kim * DESCRIPTION: Ascending callback for analysis walk. Complete method 1410b94ba42SJung-uk Kim * return analysis. 1420b94ba42SJung-uk Kim * 1430b94ba42SJung-uk Kim ******************************************************************************/ 1440b94ba42SJung-uk Kim 1450b94ba42SJung-uk Kim ACPI_STATUS 1460b94ba42SJung-uk Kim AnOperandTypecheckWalkEnd ( 1470b94ba42SJung-uk Kim ACPI_PARSE_OBJECT *Op, 1480b94ba42SJung-uk Kim UINT32 Level, 1490b94ba42SJung-uk Kim void *Context) 1500b94ba42SJung-uk Kim { 1510b94ba42SJung-uk Kim const ACPI_OPCODE_INFO *OpInfo; 1520b94ba42SJung-uk Kim UINT32 RuntimeArgTypes; 1530b94ba42SJung-uk Kim UINT32 RuntimeArgTypes2; 1540b94ba42SJung-uk Kim UINT32 RequiredBtypes; 1550b94ba42SJung-uk Kim UINT32 ThisNodeBtype; 1560b94ba42SJung-uk Kim UINT32 CommonBtypes; 1570b94ba42SJung-uk Kim UINT32 OpcodeClass; 1580b94ba42SJung-uk Kim ACPI_PARSE_OBJECT *ArgOp; 1590b94ba42SJung-uk Kim UINT32 ArgType; 1600b94ba42SJung-uk Kim 1610b94ba42SJung-uk Kim 1620b94ba42SJung-uk Kim switch (Op->Asl.AmlOpcode) 1630b94ba42SJung-uk Kim { 1640b94ba42SJung-uk Kim case AML_RAW_DATA_BYTE: 1650b94ba42SJung-uk Kim case AML_RAW_DATA_WORD: 1660b94ba42SJung-uk Kim case AML_RAW_DATA_DWORD: 1670b94ba42SJung-uk Kim case AML_RAW_DATA_QWORD: 1680b94ba42SJung-uk Kim case AML_RAW_DATA_BUFFER: 1690b94ba42SJung-uk Kim case AML_RAW_DATA_CHAIN: 1700b94ba42SJung-uk Kim case AML_PACKAGE_LENGTH: 1710b94ba42SJung-uk Kim case AML_UNASSIGNED_OPCODE: 1720b94ba42SJung-uk Kim case AML_DEFAULT_ARG_OP: 1730b94ba42SJung-uk Kim 1740b94ba42SJung-uk Kim /* Ignore the internal (compiler-only) AML opcodes */ 1750b94ba42SJung-uk Kim 1760b94ba42SJung-uk Kim return (AE_OK); 1770b94ba42SJung-uk Kim 1780b94ba42SJung-uk Kim default: 179a9d8d09cSJung-uk Kim 1800b94ba42SJung-uk Kim break; 1810b94ba42SJung-uk Kim } 1820b94ba42SJung-uk Kim 1830b94ba42SJung-uk Kim OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode); 1840b94ba42SJung-uk Kim if (!OpInfo) 1850b94ba42SJung-uk Kim { 1860b94ba42SJung-uk Kim return (AE_OK); 1870b94ba42SJung-uk Kim } 1880b94ba42SJung-uk Kim 1890b94ba42SJung-uk Kim ArgOp = Op->Asl.Child; 1900b94ba42SJung-uk Kim RuntimeArgTypes = OpInfo->RuntimeArgs; 1910b94ba42SJung-uk Kim OpcodeClass = OpInfo->Class; 1920b94ba42SJung-uk Kim 1930b94ba42SJung-uk Kim #ifdef ASL_ERROR_NAMED_OBJECT_IN_WHILE 1940b94ba42SJung-uk Kim /* 1950b94ba42SJung-uk Kim * Update 11/2008: In practice, we can't perform this check. A simple 1960b94ba42SJung-uk Kim * analysis is not sufficient. Also, it can cause errors when compiling 1970b94ba42SJung-uk Kim * disassembled code because of the way Switch operators are implemented 1980b94ba42SJung-uk Kim * (a While(One) loop with a named temp variable created within.) 1990b94ba42SJung-uk Kim */ 2000b94ba42SJung-uk Kim 2010b94ba42SJung-uk Kim /* 2020b94ba42SJung-uk Kim * If we are creating a named object, check if we are within a while loop 2030b94ba42SJung-uk Kim * by checking if the parent is a WHILE op. This is a simple analysis, but 2040b94ba42SJung-uk Kim * probably sufficient for many cases. 2050b94ba42SJung-uk Kim * 2060b94ba42SJung-uk Kim * Allow Scope(), Buffer(), and Package(). 2070b94ba42SJung-uk Kim */ 2080b94ba42SJung-uk Kim if (((OpcodeClass == AML_CLASS_NAMED_OBJECT) && (Op->Asl.AmlOpcode != AML_SCOPE_OP)) || 2090b94ba42SJung-uk Kim ((OpcodeClass == AML_CLASS_CREATE) && (OpInfo->Flags & AML_NSNODE))) 2100b94ba42SJung-uk Kim { 2110b94ba42SJung-uk Kim if (Op->Asl.Parent->Asl.AmlOpcode == AML_WHILE_OP) 2120b94ba42SJung-uk Kim { 2130b94ba42SJung-uk Kim AslError (ASL_ERROR, ASL_MSG_NAMED_OBJECT_IN_WHILE, Op, NULL); 2140b94ba42SJung-uk Kim } 2150b94ba42SJung-uk Kim } 2160b94ba42SJung-uk Kim #endif 2170b94ba42SJung-uk Kim 2180b94ba42SJung-uk Kim /* 2190b94ba42SJung-uk Kim * Special case for control opcodes IF/RETURN/WHILE since they 2200b94ba42SJung-uk Kim * have no runtime arg list (at this time) 2210b94ba42SJung-uk Kim */ 2220b94ba42SJung-uk Kim switch (Op->Asl.AmlOpcode) 2230b94ba42SJung-uk Kim { 2240b94ba42SJung-uk Kim case AML_IF_OP: 2250b94ba42SJung-uk Kim case AML_WHILE_OP: 2260b94ba42SJung-uk Kim case AML_RETURN_OP: 2270b94ba42SJung-uk Kim 2280b94ba42SJung-uk Kim if (ArgOp->Asl.ParseOpcode == PARSEOP_METHODCALL) 2290b94ba42SJung-uk Kim { 2300b94ba42SJung-uk Kim /* Check for an internal method */ 2310b94ba42SJung-uk Kim 2320b94ba42SJung-uk Kim if (AnIsInternalMethod (ArgOp)) 2330b94ba42SJung-uk Kim { 2340b94ba42SJung-uk Kim return (AE_OK); 2350b94ba42SJung-uk Kim } 2360b94ba42SJung-uk Kim 2370b94ba42SJung-uk Kim /* The lone arg is a method call, check it */ 2380b94ba42SJung-uk Kim 2390b94ba42SJung-uk Kim RequiredBtypes = AnMapArgTypeToBtype (ARGI_INTEGER); 2400b94ba42SJung-uk Kim if (Op->Asl.AmlOpcode == AML_RETURN_OP) 2410b94ba42SJung-uk Kim { 2420b94ba42SJung-uk Kim RequiredBtypes = 0xFFFFFFFF; 2430b94ba42SJung-uk Kim } 2440b94ba42SJung-uk Kim 2450b94ba42SJung-uk Kim ThisNodeBtype = AnGetBtype (ArgOp); 2460b94ba42SJung-uk Kim if (ThisNodeBtype == ACPI_UINT32_MAX) 2470b94ba42SJung-uk Kim { 2480b94ba42SJung-uk Kim return (AE_OK); 2490b94ba42SJung-uk Kim } 2500b94ba42SJung-uk Kim AnCheckMethodReturnValue (Op, OpInfo, ArgOp, 2510b94ba42SJung-uk Kim RequiredBtypes, ThisNodeBtype); 2520b94ba42SJung-uk Kim } 2530b94ba42SJung-uk Kim return (AE_OK); 2540b94ba42SJung-uk Kim 2550b94ba42SJung-uk Kim default: 256a9d8d09cSJung-uk Kim 2570b94ba42SJung-uk Kim break; 2580b94ba42SJung-uk Kim } 2590b94ba42SJung-uk Kim 2600b94ba42SJung-uk Kim /* Ignore the non-executable opcodes */ 2610b94ba42SJung-uk Kim 2620b94ba42SJung-uk Kim if (RuntimeArgTypes == ARGI_INVALID_OPCODE) 2630b94ba42SJung-uk Kim { 2640b94ba42SJung-uk Kim return (AE_OK); 2650b94ba42SJung-uk Kim } 2660b94ba42SJung-uk Kim 2670b94ba42SJung-uk Kim switch (OpcodeClass) 2680b94ba42SJung-uk Kim { 2690b94ba42SJung-uk Kim case AML_CLASS_EXECUTE: 2700b94ba42SJung-uk Kim case AML_CLASS_CREATE: 2710b94ba42SJung-uk Kim case AML_CLASS_CONTROL: 2720b94ba42SJung-uk Kim case AML_CLASS_RETURN_VALUE: 2730b94ba42SJung-uk Kim 2740b94ba42SJung-uk Kim /* TBD: Change class or fix typechecking for these */ 2750b94ba42SJung-uk Kim 2760b94ba42SJung-uk Kim if ((Op->Asl.AmlOpcode == AML_BUFFER_OP) || 2770b94ba42SJung-uk Kim (Op->Asl.AmlOpcode == AML_PACKAGE_OP) || 2780b94ba42SJung-uk Kim (Op->Asl.AmlOpcode == AML_VAR_PACKAGE_OP)) 2790b94ba42SJung-uk Kim { 2800b94ba42SJung-uk Kim break; 2810b94ba42SJung-uk Kim } 2820b94ba42SJung-uk Kim 2830b94ba42SJung-uk Kim /* Reverse the runtime argument list */ 2840b94ba42SJung-uk Kim 2850b94ba42SJung-uk Kim RuntimeArgTypes2 = 0; 2860b94ba42SJung-uk Kim while ((ArgType = GET_CURRENT_ARG_TYPE (RuntimeArgTypes))) 2870b94ba42SJung-uk Kim { 2880b94ba42SJung-uk Kim RuntimeArgTypes2 <<= ARG_TYPE_WIDTH; 2890b94ba42SJung-uk Kim RuntimeArgTypes2 |= ArgType; 2900b94ba42SJung-uk Kim INCREMENT_ARG_LIST (RuntimeArgTypes); 2910b94ba42SJung-uk Kim } 2920b94ba42SJung-uk Kim 2930b94ba42SJung-uk Kim while ((ArgType = GET_CURRENT_ARG_TYPE (RuntimeArgTypes2))) 2940b94ba42SJung-uk Kim { 2950b94ba42SJung-uk Kim RequiredBtypes = AnMapArgTypeToBtype (ArgType); 2960b94ba42SJung-uk Kim 2971c0e1b6dSJung-uk Kim if (!ArgOp) 2981c0e1b6dSJung-uk Kim { 2991c0e1b6dSJung-uk Kim AslError (ASL_ERROR, ASL_MSG_COMPILER_INTERNAL, Op, 3001c0e1b6dSJung-uk Kim "Null ArgOp in argument loop"); 3011c0e1b6dSJung-uk Kim AslAbort (); 3021c0e1b6dSJung-uk Kim } 3031c0e1b6dSJung-uk Kim 3040b94ba42SJung-uk Kim ThisNodeBtype = AnGetBtype (ArgOp); 3050b94ba42SJung-uk Kim if (ThisNodeBtype == ACPI_UINT32_MAX) 3060b94ba42SJung-uk Kim { 3070b94ba42SJung-uk Kim goto NextArgument; 3080b94ba42SJung-uk Kim } 3090b94ba42SJung-uk Kim 3100b94ba42SJung-uk Kim /* Examine the arg based on the required type of the arg */ 3110b94ba42SJung-uk Kim 3120b94ba42SJung-uk Kim switch (ArgType) 3130b94ba42SJung-uk Kim { 3140b94ba42SJung-uk Kim case ARGI_TARGETREF: 3150b94ba42SJung-uk Kim 3160b94ba42SJung-uk Kim if (ArgOp->Asl.ParseOpcode == PARSEOP_ZERO) 3170b94ba42SJung-uk Kim { 3180b94ba42SJung-uk Kim /* ZERO is the placeholder for "don't store result" */ 3190b94ba42SJung-uk Kim 3200b94ba42SJung-uk Kim ThisNodeBtype = RequiredBtypes; 3210b94ba42SJung-uk Kim break; 3220b94ba42SJung-uk Kim } 3230b94ba42SJung-uk Kim 3240b94ba42SJung-uk Kim if (ArgOp->Asl.ParseOpcode == PARSEOP_INTEGER) 3250b94ba42SJung-uk Kim { 3260b94ba42SJung-uk Kim /* 3270b94ba42SJung-uk Kim * This is the case where an original reference to a resource 3280b94ba42SJung-uk Kim * descriptor field has been replaced by an (Integer) offset. 3290b94ba42SJung-uk Kim * These named fields are supported at compile-time only; 3300b94ba42SJung-uk Kim * the names are not passed to the interpreter (via the AML). 3310b94ba42SJung-uk Kim */ 3320b94ba42SJung-uk Kim if ((ArgOp->Asl.Node->Type == ACPI_TYPE_LOCAL_RESOURCE_FIELD) || 3330b94ba42SJung-uk Kim (ArgOp->Asl.Node->Type == ACPI_TYPE_LOCAL_RESOURCE)) 3340b94ba42SJung-uk Kim { 3350b94ba42SJung-uk Kim AslError (ASL_ERROR, ASL_MSG_RESOURCE_FIELD, ArgOp, NULL); 3360b94ba42SJung-uk Kim } 3370b94ba42SJung-uk Kim else 3380b94ba42SJung-uk Kim { 3390b94ba42SJung-uk Kim AslError (ASL_ERROR, ASL_MSG_INVALID_TYPE, ArgOp, NULL); 3400b94ba42SJung-uk Kim } 3410b94ba42SJung-uk Kim break; 3420b94ba42SJung-uk Kim } 3430b94ba42SJung-uk Kim 3440b94ba42SJung-uk Kim if ((ArgOp->Asl.ParseOpcode == PARSEOP_METHODCALL) || 3450b94ba42SJung-uk Kim (ArgOp->Asl.ParseOpcode == PARSEOP_DEREFOF)) 3460b94ba42SJung-uk Kim { 3470b94ba42SJung-uk Kim break; 3480b94ba42SJung-uk Kim } 3490b94ba42SJung-uk Kim 3500b94ba42SJung-uk Kim ThisNodeBtype = RequiredBtypes; 3510b94ba42SJung-uk Kim break; 3520b94ba42SJung-uk Kim 3530b94ba42SJung-uk Kim 3540b94ba42SJung-uk Kim case ARGI_REFERENCE: /* References */ 3550b94ba42SJung-uk Kim case ARGI_INTEGER_REF: 3560b94ba42SJung-uk Kim case ARGI_OBJECT_REF: 3570b94ba42SJung-uk Kim case ARGI_DEVICE_REF: 3580b94ba42SJung-uk Kim 3590b94ba42SJung-uk Kim switch (ArgOp->Asl.ParseOpcode) 3600b94ba42SJung-uk Kim { 3610b94ba42SJung-uk Kim case PARSEOP_LOCAL0: 3620b94ba42SJung-uk Kim case PARSEOP_LOCAL1: 3630b94ba42SJung-uk Kim case PARSEOP_LOCAL2: 3640b94ba42SJung-uk Kim case PARSEOP_LOCAL3: 3650b94ba42SJung-uk Kim case PARSEOP_LOCAL4: 3660b94ba42SJung-uk Kim case PARSEOP_LOCAL5: 3670b94ba42SJung-uk Kim case PARSEOP_LOCAL6: 3680b94ba42SJung-uk Kim case PARSEOP_LOCAL7: 3690b94ba42SJung-uk Kim 3700b94ba42SJung-uk Kim /* TBD: implement analysis of current value (type) of the local */ 3710b94ba42SJung-uk Kim /* For now, just treat any local as a typematch */ 3720b94ba42SJung-uk Kim 3730b94ba42SJung-uk Kim /*ThisNodeBtype = RequiredBtypes;*/ 3740b94ba42SJung-uk Kim break; 3750b94ba42SJung-uk Kim 3760b94ba42SJung-uk Kim case PARSEOP_ARG0: 3770b94ba42SJung-uk Kim case PARSEOP_ARG1: 3780b94ba42SJung-uk Kim case PARSEOP_ARG2: 3790b94ba42SJung-uk Kim case PARSEOP_ARG3: 3800b94ba42SJung-uk Kim case PARSEOP_ARG4: 3810b94ba42SJung-uk Kim case PARSEOP_ARG5: 3820b94ba42SJung-uk Kim case PARSEOP_ARG6: 3830b94ba42SJung-uk Kim 3840b94ba42SJung-uk Kim /* Hard to analyze argument types, sow we won't */ 3850b94ba42SJung-uk Kim /* For now, just treat any arg as a typematch */ 3860b94ba42SJung-uk Kim 3870b94ba42SJung-uk Kim /* ThisNodeBtype = RequiredBtypes; */ 3880b94ba42SJung-uk Kim break; 3890b94ba42SJung-uk Kim 3900b94ba42SJung-uk Kim case PARSEOP_DEBUG: 391a9d8d09cSJung-uk Kim 3920b94ba42SJung-uk Kim break; 3930b94ba42SJung-uk Kim 3940b94ba42SJung-uk Kim case PARSEOP_REFOF: 3950b94ba42SJung-uk Kim case PARSEOP_INDEX: 3960b94ba42SJung-uk Kim default: 397a9d8d09cSJung-uk Kim 3980b94ba42SJung-uk Kim break; 3990b94ba42SJung-uk Kim 4000b94ba42SJung-uk Kim } 4010b94ba42SJung-uk Kim break; 4020b94ba42SJung-uk Kim 4030b94ba42SJung-uk Kim case ARGI_INTEGER: 4040b94ba42SJung-uk Kim default: 405a9d8d09cSJung-uk Kim 4060b94ba42SJung-uk Kim break; 4070b94ba42SJung-uk Kim } 4080b94ba42SJung-uk Kim 4090b94ba42SJung-uk Kim 4100b94ba42SJung-uk Kim CommonBtypes = ThisNodeBtype & RequiredBtypes; 4110b94ba42SJung-uk Kim 4120b94ba42SJung-uk Kim if (ArgOp->Asl.ParseOpcode == PARSEOP_METHODCALL) 4130b94ba42SJung-uk Kim { 4140b94ba42SJung-uk Kim if (AnIsInternalMethod (ArgOp)) 4150b94ba42SJung-uk Kim { 4160b94ba42SJung-uk Kim return (AE_OK); 4170b94ba42SJung-uk Kim } 4180b94ba42SJung-uk Kim 4190b94ba42SJung-uk Kim /* Check a method call for a valid return value */ 4200b94ba42SJung-uk Kim 4210b94ba42SJung-uk Kim AnCheckMethodReturnValue (Op, OpInfo, ArgOp, 4220b94ba42SJung-uk Kim RequiredBtypes, ThisNodeBtype); 4230b94ba42SJung-uk Kim } 4240b94ba42SJung-uk Kim 4250b94ba42SJung-uk Kim /* 4260b94ba42SJung-uk Kim * Now check if the actual type(s) match at least one 4270b94ba42SJung-uk Kim * bit to the required type 4280b94ba42SJung-uk Kim */ 4290b94ba42SJung-uk Kim else if (!CommonBtypes) 4300b94ba42SJung-uk Kim { 4310b94ba42SJung-uk Kim /* No match -- this is a type mismatch error */ 4320b94ba42SJung-uk Kim 4330b94ba42SJung-uk Kim AnFormatBtype (StringBuffer, ThisNodeBtype); 4340b94ba42SJung-uk Kim AnFormatBtype (StringBuffer2, RequiredBtypes); 4350b94ba42SJung-uk Kim 4360b94ba42SJung-uk Kim sprintf (MsgBuffer, "[%s] found, %s operator requires [%s]", 4370b94ba42SJung-uk Kim StringBuffer, OpInfo->Name, StringBuffer2); 4380b94ba42SJung-uk Kim 4390b94ba42SJung-uk Kim AslError (ASL_ERROR, ASL_MSG_INVALID_TYPE, ArgOp, MsgBuffer); 4400b94ba42SJung-uk Kim } 4410b94ba42SJung-uk Kim 4420b94ba42SJung-uk Kim NextArgument: 4430b94ba42SJung-uk Kim ArgOp = ArgOp->Asl.Next; 4440b94ba42SJung-uk Kim INCREMENT_ARG_LIST (RuntimeArgTypes2); 4450b94ba42SJung-uk Kim } 4460b94ba42SJung-uk Kim break; 4470b94ba42SJung-uk Kim 4480b94ba42SJung-uk Kim default: 449a9d8d09cSJung-uk Kim 4500b94ba42SJung-uk Kim break; 4510b94ba42SJung-uk Kim } 4520b94ba42SJung-uk Kim 4530b94ba42SJung-uk Kim return (AE_OK); 4540b94ba42SJung-uk Kim } 4550b94ba42SJung-uk Kim 4560b94ba42SJung-uk Kim 4570b94ba42SJung-uk Kim /******************************************************************************* 4580b94ba42SJung-uk Kim * 4590b94ba42SJung-uk Kim * FUNCTION: AnOtherSemanticAnalysisWalkBegin 4600b94ba42SJung-uk Kim * 4610b94ba42SJung-uk Kim * PARAMETERS: ASL_WALK_CALLBACK 4620b94ba42SJung-uk Kim * 4630b94ba42SJung-uk Kim * RETURN: Status 4640b94ba42SJung-uk Kim * 4650b94ba42SJung-uk Kim * DESCRIPTION: Descending callback for the analysis walk. Checks for 4660b94ba42SJung-uk Kim * miscellaneous issues in the code. 4670b94ba42SJung-uk Kim * 4680b94ba42SJung-uk Kim ******************************************************************************/ 4690b94ba42SJung-uk Kim 4700b94ba42SJung-uk Kim ACPI_STATUS 4710b94ba42SJung-uk Kim AnOtherSemanticAnalysisWalkBegin ( 4720b94ba42SJung-uk Kim ACPI_PARSE_OBJECT *Op, 4730b94ba42SJung-uk Kim UINT32 Level, 4740b94ba42SJung-uk Kim void *Context) 4750b94ba42SJung-uk Kim { 4760b94ba42SJung-uk Kim ACPI_PARSE_OBJECT *ArgNode; 4770b94ba42SJung-uk Kim ACPI_PARSE_OBJECT *PrevArgNode = NULL; 4780b94ba42SJung-uk Kim const ACPI_OPCODE_INFO *OpInfo; 4793f0275a0SJung-uk Kim ACPI_NAMESPACE_NODE *Node; 4800b94ba42SJung-uk Kim 4810b94ba42SJung-uk Kim 4820b94ba42SJung-uk Kim OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode); 4830b94ba42SJung-uk Kim 4840b94ba42SJung-uk Kim /* 4850b94ba42SJung-uk Kim * Determine if an execution class operator actually does something by 4860b94ba42SJung-uk Kim * checking if it has a target and/or the function return value is used. 4870b94ba42SJung-uk Kim * (Target is optional, so a standalone statement can actually do nothing.) 4880b94ba42SJung-uk Kim */ 4890b94ba42SJung-uk Kim if ((OpInfo->Class == AML_CLASS_EXECUTE) && 4900b94ba42SJung-uk Kim (OpInfo->Flags & AML_HAS_RETVAL) && 4910b94ba42SJung-uk Kim (!AnIsResultUsed (Op))) 4920b94ba42SJung-uk Kim { 4930b94ba42SJung-uk Kim if (OpInfo->Flags & AML_HAS_TARGET) 4940b94ba42SJung-uk Kim { 4950b94ba42SJung-uk Kim /* 4960b94ba42SJung-uk Kim * Find the target node, it is always the last child. If the traget 4970b94ba42SJung-uk Kim * is not specified in the ASL, a default node of type Zero was 4980b94ba42SJung-uk Kim * created by the parser. 4990b94ba42SJung-uk Kim */ 5000b94ba42SJung-uk Kim ArgNode = Op->Asl.Child; 5010b94ba42SJung-uk Kim while (ArgNode->Asl.Next) 5020b94ba42SJung-uk Kim { 5030b94ba42SJung-uk Kim PrevArgNode = ArgNode; 5040b94ba42SJung-uk Kim ArgNode = ArgNode->Asl.Next; 5050b94ba42SJung-uk Kim } 5060b94ba42SJung-uk Kim 5070b94ba42SJung-uk Kim /* Divide() is the only weird case, it has two targets */ 5080b94ba42SJung-uk Kim 5090b94ba42SJung-uk Kim if (Op->Asl.AmlOpcode == AML_DIVIDE_OP) 5100b94ba42SJung-uk Kim { 5110b94ba42SJung-uk Kim if ((ArgNode->Asl.ParseOpcode == PARSEOP_ZERO) && 5120b94ba42SJung-uk Kim (PrevArgNode) && 5130b94ba42SJung-uk Kim (PrevArgNode->Asl.ParseOpcode == PARSEOP_ZERO)) 5140b94ba42SJung-uk Kim { 5159c7c683cSJung-uk Kim AslError (ASL_ERROR, ASL_MSG_RESULT_NOT_USED, 5160b94ba42SJung-uk Kim Op, Op->Asl.ExternalName); 5170b94ba42SJung-uk Kim } 5180b94ba42SJung-uk Kim } 5190b94ba42SJung-uk Kim else if (ArgNode->Asl.ParseOpcode == PARSEOP_ZERO) 5200b94ba42SJung-uk Kim { 5219c7c683cSJung-uk Kim AslError (ASL_ERROR, ASL_MSG_RESULT_NOT_USED, 5220b94ba42SJung-uk Kim Op, Op->Asl.ExternalName); 5230b94ba42SJung-uk Kim } 5240b94ba42SJung-uk Kim } 5250b94ba42SJung-uk Kim else 5260b94ba42SJung-uk Kim { 5270b94ba42SJung-uk Kim /* 5280b94ba42SJung-uk Kim * Has no target and the result is not used. Only a couple opcodes 5290b94ba42SJung-uk Kim * can have this combination. 5300b94ba42SJung-uk Kim */ 5310b94ba42SJung-uk Kim switch (Op->Asl.ParseOpcode) 5320b94ba42SJung-uk Kim { 5330b94ba42SJung-uk Kim case PARSEOP_ACQUIRE: 5340b94ba42SJung-uk Kim case PARSEOP_WAIT: 5350b94ba42SJung-uk Kim case PARSEOP_LOADTABLE: 536a9d8d09cSJung-uk Kim 5370b94ba42SJung-uk Kim break; 5380b94ba42SJung-uk Kim 5390b94ba42SJung-uk Kim default: 540a9d8d09cSJung-uk Kim 5419c7c683cSJung-uk Kim AslError (ASL_ERROR, ASL_MSG_RESULT_NOT_USED, 5420b94ba42SJung-uk Kim Op, Op->Asl.ExternalName); 5430b94ba42SJung-uk Kim break; 5440b94ba42SJung-uk Kim } 5450b94ba42SJung-uk Kim } 5460b94ba42SJung-uk Kim } 5470b94ba42SJung-uk Kim 5480b94ba42SJung-uk Kim 5490b94ba42SJung-uk Kim /* 5500b94ba42SJung-uk Kim * Semantic checks for individual ASL operators 5510b94ba42SJung-uk Kim */ 5520b94ba42SJung-uk Kim switch (Op->Asl.ParseOpcode) 5530b94ba42SJung-uk Kim { 5540b94ba42SJung-uk Kim case PARSEOP_ACQUIRE: 5550b94ba42SJung-uk Kim case PARSEOP_WAIT: 5560b94ba42SJung-uk Kim /* 5570b94ba42SJung-uk Kim * Emit a warning if the timeout parameter for these operators is not 5580b94ba42SJung-uk Kim * ACPI_WAIT_FOREVER, and the result value from the operator is not 5590b94ba42SJung-uk Kim * checked, meaning that a timeout could happen, but the code 5600b94ba42SJung-uk Kim * would not know about it. 5610b94ba42SJung-uk Kim */ 5620b94ba42SJung-uk Kim 5630b94ba42SJung-uk Kim /* First child is the namepath, 2nd child is timeout */ 5640b94ba42SJung-uk Kim 5650b94ba42SJung-uk Kim ArgNode = Op->Asl.Child; 5660b94ba42SJung-uk Kim ArgNode = ArgNode->Asl.Next; 5670b94ba42SJung-uk Kim 5680b94ba42SJung-uk Kim /* 5690b94ba42SJung-uk Kim * Check for the WAIT_FOREVER case - defined by the ACPI spec to be 5700b94ba42SJung-uk Kim * 0xFFFF or greater 5710b94ba42SJung-uk Kim */ 5720b94ba42SJung-uk Kim if (((ArgNode->Asl.ParseOpcode == PARSEOP_WORDCONST) || 5730b94ba42SJung-uk Kim (ArgNode->Asl.ParseOpcode == PARSEOP_INTEGER)) && 5740b94ba42SJung-uk Kim (ArgNode->Asl.Value.Integer >= (UINT64) ACPI_WAIT_FOREVER)) 5750b94ba42SJung-uk Kim { 5760b94ba42SJung-uk Kim break; 5770b94ba42SJung-uk Kim } 5780b94ba42SJung-uk Kim 5790b94ba42SJung-uk Kim /* 5800b94ba42SJung-uk Kim * The operation could timeout. If the return value is not used 5810b94ba42SJung-uk Kim * (indicates timeout occurred), issue a warning 5820b94ba42SJung-uk Kim */ 5830b94ba42SJung-uk Kim if (!AnIsResultUsed (Op)) 5840b94ba42SJung-uk Kim { 5850b94ba42SJung-uk Kim AslError (ASL_WARNING, ASL_MSG_TIMEOUT, ArgNode, 5860b94ba42SJung-uk Kim Op->Asl.ExternalName); 5870b94ba42SJung-uk Kim } 5880b94ba42SJung-uk Kim break; 5890b94ba42SJung-uk Kim 5900b94ba42SJung-uk Kim case PARSEOP_CREATEFIELD: 5910b94ba42SJung-uk Kim /* 5920b94ba42SJung-uk Kim * Check for a zero Length (NumBits) operand. NumBits is the 3rd operand 5930b94ba42SJung-uk Kim */ 5940b94ba42SJung-uk Kim ArgNode = Op->Asl.Child; 5950b94ba42SJung-uk Kim ArgNode = ArgNode->Asl.Next; 5960b94ba42SJung-uk Kim ArgNode = ArgNode->Asl.Next; 5970b94ba42SJung-uk Kim 5980b94ba42SJung-uk Kim if ((ArgNode->Asl.ParseOpcode == PARSEOP_ZERO) || 5990b94ba42SJung-uk Kim ((ArgNode->Asl.ParseOpcode == PARSEOP_INTEGER) && 6000b94ba42SJung-uk Kim (ArgNode->Asl.Value.Integer == 0))) 6010b94ba42SJung-uk Kim { 6020b94ba42SJung-uk Kim AslError (ASL_ERROR, ASL_MSG_NON_ZERO, ArgNode, NULL); 6030b94ba42SJung-uk Kim } 6040b94ba42SJung-uk Kim break; 6050b94ba42SJung-uk Kim 6063f0275a0SJung-uk Kim case PARSEOP_CONNECTION: 6073f0275a0SJung-uk Kim /* 6083f0275a0SJung-uk Kim * Ensure that the referenced operation region has the correct SPACE_ID. 6093f0275a0SJung-uk Kim * From the grammar/parser, we know the parent is a FIELD definition. 6103f0275a0SJung-uk Kim */ 6113f0275a0SJung-uk Kim ArgNode = Op->Asl.Parent; /* Field definition */ 6123f0275a0SJung-uk Kim ArgNode = ArgNode->Asl.Child; /* First child is the OpRegion Name */ 6133f0275a0SJung-uk Kim Node = ArgNode->Asl.Node; /* OpRegion namespace node */ 614313a0c13SJung-uk Kim if (!Node) 615313a0c13SJung-uk Kim { 616313a0c13SJung-uk Kim break; 617313a0c13SJung-uk Kim } 6183f0275a0SJung-uk Kim 6193f0275a0SJung-uk Kim ArgNode = Node->Op; /* OpRegion definition */ 6203f0275a0SJung-uk Kim ArgNode = ArgNode->Asl.Child; /* First child is the OpRegion Name */ 6213f0275a0SJung-uk Kim ArgNode = ArgNode->Asl.Next; /* Next peer is the SPACE_ID (what we want) */ 6223f0275a0SJung-uk Kim 6233f0275a0SJung-uk Kim /* 6243f0275a0SJung-uk Kim * The Connection() operator is only valid for the following operation 6253f0275a0SJung-uk Kim * region SpaceIds: GeneralPurposeIo and GenericSerialBus. 6263f0275a0SJung-uk Kim */ 6273f0275a0SJung-uk Kim if ((ArgNode->Asl.Value.Integer != ACPI_ADR_SPACE_GPIO) && 6283f0275a0SJung-uk Kim (ArgNode->Asl.Value.Integer != ACPI_ADR_SPACE_GSBUS)) 6293f0275a0SJung-uk Kim { 6303f0275a0SJung-uk Kim AslError (ASL_ERROR, ASL_MSG_CONNECTION_INVALID, Op, NULL); 6313f0275a0SJung-uk Kim } 6323f0275a0SJung-uk Kim break; 6333f0275a0SJung-uk Kim 6343f0275a0SJung-uk Kim case PARSEOP_FIELD: 6353f0275a0SJung-uk Kim /* 6363f0275a0SJung-uk Kim * Ensure that fields for GeneralPurposeIo and GenericSerialBus 6373f0275a0SJung-uk Kim * contain at least one Connection() operator 6383f0275a0SJung-uk Kim */ 6393f0275a0SJung-uk Kim ArgNode = Op->Asl.Child; /* 1st child is the OpRegion Name */ 6403f0275a0SJung-uk Kim Node = ArgNode->Asl.Node; /* OpRegion namespace node */ 6413f0275a0SJung-uk Kim if (!Node) 6423f0275a0SJung-uk Kim { 6433f0275a0SJung-uk Kim break; 6443f0275a0SJung-uk Kim } 6453f0275a0SJung-uk Kim 6463f0275a0SJung-uk Kim ArgNode = Node->Op; /* OpRegion definition */ 6473f0275a0SJung-uk Kim ArgNode = ArgNode->Asl.Child; /* First child is the OpRegion Name */ 6483f0275a0SJung-uk Kim ArgNode = ArgNode->Asl.Next; /* Next peer is the SPACE_ID (what we want) */ 6493f0275a0SJung-uk Kim 6503f0275a0SJung-uk Kim /* We are only interested in GeneralPurposeIo and GenericSerialBus */ 6513f0275a0SJung-uk Kim 6523f0275a0SJung-uk Kim if ((ArgNode->Asl.Value.Integer != ACPI_ADR_SPACE_GPIO) && 6533f0275a0SJung-uk Kim (ArgNode->Asl.Value.Integer != ACPI_ADR_SPACE_GSBUS)) 6543f0275a0SJung-uk Kim { 6553f0275a0SJung-uk Kim break; 6563f0275a0SJung-uk Kim } 6573f0275a0SJung-uk Kim 6583f0275a0SJung-uk Kim ArgNode = Op->Asl.Child; /* 1st child is the OpRegion Name */ 6593f0275a0SJung-uk Kim ArgNode = ArgNode->Asl.Next; /* AccessType */ 6603f0275a0SJung-uk Kim ArgNode = ArgNode->Asl.Next; /* LockRule */ 6613f0275a0SJung-uk Kim ArgNode = ArgNode->Asl.Next; /* UpdateRule */ 6623f0275a0SJung-uk Kim ArgNode = ArgNode->Asl.Next; /* Start of FieldUnitList */ 6633f0275a0SJung-uk Kim 6643f0275a0SJung-uk Kim /* Walk the FieldUnitList */ 6653f0275a0SJung-uk Kim 6663f0275a0SJung-uk Kim while (ArgNode) 6673f0275a0SJung-uk Kim { 6683f0275a0SJung-uk Kim if (ArgNode->Asl.ParseOpcode == PARSEOP_CONNECTION) 6693f0275a0SJung-uk Kim { 6703f0275a0SJung-uk Kim break; 6713f0275a0SJung-uk Kim } 6723f0275a0SJung-uk Kim else if (ArgNode->Asl.ParseOpcode == PARSEOP_NAMESEG) 6733f0275a0SJung-uk Kim { 6743f0275a0SJung-uk Kim AslError (ASL_ERROR, ASL_MSG_CONNECTION_MISSING, ArgNode, NULL); 6753f0275a0SJung-uk Kim break; 6763f0275a0SJung-uk Kim } 6773f0275a0SJung-uk Kim 6783f0275a0SJung-uk Kim ArgNode = ArgNode->Asl.Next; 6793f0275a0SJung-uk Kim } 6803f0275a0SJung-uk Kim break; 6813f0275a0SJung-uk Kim 6820b94ba42SJung-uk Kim default: 683a9d8d09cSJung-uk Kim 6840b94ba42SJung-uk Kim break; 6850b94ba42SJung-uk Kim } 6860b94ba42SJung-uk Kim 6870b94ba42SJung-uk Kim return (AE_OK); 6880b94ba42SJung-uk Kim } 689