10b94ba42SJung-uk Kim /****************************************************************************** 20b94ba42SJung-uk Kim * 30b94ba42SJung-uk Kim * Module Name: aslwalks.c - major analytical parse tree walks 40b94ba42SJung-uk Kim * 50b94ba42SJung-uk Kim *****************************************************************************/ 60b94ba42SJung-uk Kim 70b94ba42SJung-uk Kim /* 80b94ba42SJung-uk Kim * Copyright (C) 2000 - 2011, 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 450b94ba42SJung-uk Kim #include <contrib/dev/acpica/compiler/aslcompiler.h> 460b94ba42SJung-uk Kim #include "aslcompiler.y.h" 470b94ba42SJung-uk Kim #include <contrib/dev/acpica/include/acparser.h> 480b94ba42SJung-uk Kim #include <contrib/dev/acpica/include/amlcode.h> 490b94ba42SJung-uk Kim 500b94ba42SJung-uk Kim 510b94ba42SJung-uk Kim #define _COMPONENT ACPI_COMPILER 520b94ba42SJung-uk Kim ACPI_MODULE_NAME ("aslwalks") 530b94ba42SJung-uk Kim 540b94ba42SJung-uk Kim 550b94ba42SJung-uk Kim /******************************************************************************* 560b94ba42SJung-uk Kim * 570b94ba42SJung-uk Kim * FUNCTION: AnMethodAnalysisWalkBegin 580b94ba42SJung-uk Kim * 590b94ba42SJung-uk Kim * PARAMETERS: ASL_WALK_CALLBACK 600b94ba42SJung-uk Kim * 610b94ba42SJung-uk Kim * RETURN: Status 620b94ba42SJung-uk Kim * 630b94ba42SJung-uk Kim * DESCRIPTION: Descending callback for the analysis walk. 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 AnMethodAnalysisWalkBegin ( 720b94ba42SJung-uk Kim ACPI_PARSE_OBJECT *Op, 730b94ba42SJung-uk Kim UINT32 Level, 740b94ba42SJung-uk Kim void *Context) 750b94ba42SJung-uk Kim { 760b94ba42SJung-uk Kim ASL_ANALYSIS_WALK_INFO *WalkInfo = (ASL_ANALYSIS_WALK_INFO *) Context; 770b94ba42SJung-uk Kim ASL_METHOD_INFO *MethodInfo = WalkInfo->MethodStack; 780b94ba42SJung-uk Kim ACPI_PARSE_OBJECT *Next; 790b94ba42SJung-uk Kim UINT32 RegisterNumber; 800b94ba42SJung-uk Kim UINT32 i; 810b94ba42SJung-uk Kim char LocalName[] = "Local0"; 820b94ba42SJung-uk Kim char ArgName[] = "Arg0"; 830b94ba42SJung-uk Kim ACPI_PARSE_OBJECT *ArgNode; 840b94ba42SJung-uk Kim ACPI_PARSE_OBJECT *NextType; 850b94ba42SJung-uk Kim ACPI_PARSE_OBJECT *NextParamType; 860b94ba42SJung-uk Kim UINT8 ActualArgs = 0; 870b94ba42SJung-uk Kim 880b94ba42SJung-uk Kim 890b94ba42SJung-uk Kim switch (Op->Asl.ParseOpcode) 900b94ba42SJung-uk Kim { 910b94ba42SJung-uk Kim case PARSEOP_METHOD: 920b94ba42SJung-uk Kim 930b94ba42SJung-uk Kim TotalMethods++; 940b94ba42SJung-uk Kim 950b94ba42SJung-uk Kim /* Create and init method info */ 960b94ba42SJung-uk Kim 970b94ba42SJung-uk Kim MethodInfo = UtLocalCalloc (sizeof (ASL_METHOD_INFO)); 980b94ba42SJung-uk Kim MethodInfo->Next = WalkInfo->MethodStack; 990b94ba42SJung-uk Kim MethodInfo->Op = Op; 1000b94ba42SJung-uk Kim 1010b94ba42SJung-uk Kim WalkInfo->MethodStack = MethodInfo; 1020b94ba42SJung-uk Kim 1030b94ba42SJung-uk Kim /* Get the name node, ignored here */ 1040b94ba42SJung-uk Kim 1050b94ba42SJung-uk Kim Next = Op->Asl.Child; 1060b94ba42SJung-uk Kim 1070b94ba42SJung-uk Kim /* Get the NumArguments node */ 1080b94ba42SJung-uk Kim 1090b94ba42SJung-uk Kim Next = Next->Asl.Next; 1100b94ba42SJung-uk Kim MethodInfo->NumArguments = (UINT8) 1110b94ba42SJung-uk Kim (((UINT8) Next->Asl.Value.Integer) & 0x07); 1120b94ba42SJung-uk Kim 1130b94ba42SJung-uk Kim /* Get the SerializeRule and SyncLevel nodes, ignored here */ 1140b94ba42SJung-uk Kim 1150b94ba42SJung-uk Kim Next = Next->Asl.Next; 1160b94ba42SJung-uk Kim Next = Next->Asl.Next; 1170b94ba42SJung-uk Kim ArgNode = Next; 1180b94ba42SJung-uk Kim 1190b94ba42SJung-uk Kim /* Get the ReturnType node */ 1200b94ba42SJung-uk Kim 1210b94ba42SJung-uk Kim Next = Next->Asl.Next; 1220b94ba42SJung-uk Kim 1230b94ba42SJung-uk Kim NextType = Next->Asl.Child; 1240b94ba42SJung-uk Kim while (NextType) 1250b94ba42SJung-uk Kim { 1260b94ba42SJung-uk Kim /* Get and map each of the ReturnTypes */ 1270b94ba42SJung-uk Kim 1280b94ba42SJung-uk Kim MethodInfo->ValidReturnTypes |= AnMapObjTypeToBtype (NextType); 1290b94ba42SJung-uk Kim NextType->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG; 1300b94ba42SJung-uk Kim NextType = NextType->Asl.Next; 1310b94ba42SJung-uk Kim } 1320b94ba42SJung-uk Kim 1330b94ba42SJung-uk Kim /* Get the ParameterType node */ 1340b94ba42SJung-uk Kim 1350b94ba42SJung-uk Kim Next = Next->Asl.Next; 1360b94ba42SJung-uk Kim 1370b94ba42SJung-uk Kim NextType = Next->Asl.Child; 1380b94ba42SJung-uk Kim while (NextType) 1390b94ba42SJung-uk Kim { 1400b94ba42SJung-uk Kim if (NextType->Asl.ParseOpcode == PARSEOP_DEFAULT_ARG) 1410b94ba42SJung-uk Kim { 1420b94ba42SJung-uk Kim NextParamType = NextType->Asl.Child; 1430b94ba42SJung-uk Kim while (NextParamType) 1440b94ba42SJung-uk Kim { 1450b94ba42SJung-uk Kim MethodInfo->ValidArgTypes[ActualArgs] |= AnMapObjTypeToBtype (NextParamType); 1460b94ba42SJung-uk Kim NextParamType->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG; 1470b94ba42SJung-uk Kim NextParamType = NextParamType->Asl.Next; 1480b94ba42SJung-uk Kim } 1490b94ba42SJung-uk Kim } 1500b94ba42SJung-uk Kim else 1510b94ba42SJung-uk Kim { 1520b94ba42SJung-uk Kim MethodInfo->ValidArgTypes[ActualArgs] = 1530b94ba42SJung-uk Kim AnMapObjTypeToBtype (NextType); 1540b94ba42SJung-uk Kim NextType->Asl.ParseOpcode = PARSEOP_DEFAULT_ARG; 1550b94ba42SJung-uk Kim ActualArgs++; 1560b94ba42SJung-uk Kim } 1570b94ba42SJung-uk Kim 1580b94ba42SJung-uk Kim NextType = NextType->Asl.Next; 1590b94ba42SJung-uk Kim } 1600b94ba42SJung-uk Kim 1610b94ba42SJung-uk Kim if ((MethodInfo->NumArguments) && 1620b94ba42SJung-uk Kim (MethodInfo->NumArguments != ActualArgs)) 1630b94ba42SJung-uk Kim { 1640b94ba42SJung-uk Kim /* error: Param list did not match number of args */ 1650b94ba42SJung-uk Kim } 1660b94ba42SJung-uk Kim 1670b94ba42SJung-uk Kim /* Allow numarguments == 0 for Function() */ 1680b94ba42SJung-uk Kim 1690b94ba42SJung-uk Kim if ((!MethodInfo->NumArguments) && (ActualArgs)) 1700b94ba42SJung-uk Kim { 1710b94ba42SJung-uk Kim MethodInfo->NumArguments = ActualArgs; 1720b94ba42SJung-uk Kim ArgNode->Asl.Value.Integer |= ActualArgs; 1730b94ba42SJung-uk Kim } 1740b94ba42SJung-uk Kim 1750b94ba42SJung-uk Kim /* 1760b94ba42SJung-uk Kim * Actual arguments are initialized at method entry. 1770b94ba42SJung-uk Kim * All other ArgX "registers" can be used as locals, so we 1780b94ba42SJung-uk Kim * track their initialization. 1790b94ba42SJung-uk Kim */ 1800b94ba42SJung-uk Kim for (i = 0; i < MethodInfo->NumArguments; i++) 1810b94ba42SJung-uk Kim { 1820b94ba42SJung-uk Kim MethodInfo->ArgInitialized[i] = TRUE; 1830b94ba42SJung-uk Kim } 1840b94ba42SJung-uk Kim break; 1850b94ba42SJung-uk Kim 1860b94ba42SJung-uk Kim 1870b94ba42SJung-uk Kim case PARSEOP_METHODCALL: 1880b94ba42SJung-uk Kim 1890b94ba42SJung-uk Kim if (MethodInfo && 1900b94ba42SJung-uk Kim (Op->Asl.Node == MethodInfo->Op->Asl.Node)) 1910b94ba42SJung-uk Kim { 1920b94ba42SJung-uk Kim AslError (ASL_REMARK, ASL_MSG_RECURSION, Op, Op->Asl.ExternalName); 1930b94ba42SJung-uk Kim } 1940b94ba42SJung-uk Kim break; 1950b94ba42SJung-uk Kim 1960b94ba42SJung-uk Kim 1970b94ba42SJung-uk Kim case PARSEOP_LOCAL0: 1980b94ba42SJung-uk Kim case PARSEOP_LOCAL1: 1990b94ba42SJung-uk Kim case PARSEOP_LOCAL2: 2000b94ba42SJung-uk Kim case PARSEOP_LOCAL3: 2010b94ba42SJung-uk Kim case PARSEOP_LOCAL4: 2020b94ba42SJung-uk Kim case PARSEOP_LOCAL5: 2030b94ba42SJung-uk Kim case PARSEOP_LOCAL6: 2040b94ba42SJung-uk Kim case PARSEOP_LOCAL7: 2050b94ba42SJung-uk Kim 2060b94ba42SJung-uk Kim if (!MethodInfo) 2070b94ba42SJung-uk Kim { 2080b94ba42SJung-uk Kim /* 2090b94ba42SJung-uk Kim * Local was used outside a control method, or there was an error 2100b94ba42SJung-uk Kim * in the method declaration. 2110b94ba42SJung-uk Kim */ 2120b94ba42SJung-uk Kim AslError (ASL_REMARK, ASL_MSG_LOCAL_OUTSIDE_METHOD, Op, Op->Asl.ExternalName); 2130b94ba42SJung-uk Kim return (AE_ERROR); 2140b94ba42SJung-uk Kim } 2150b94ba42SJung-uk Kim 2160b94ba42SJung-uk Kim RegisterNumber = (Op->Asl.AmlOpcode & 0x000F); 2170b94ba42SJung-uk Kim 2180b94ba42SJung-uk Kim /* 2190b94ba42SJung-uk Kim * If the local is being used as a target, mark the local 2200b94ba42SJung-uk Kim * initialized 2210b94ba42SJung-uk Kim */ 2220b94ba42SJung-uk Kim if (Op->Asl.CompileFlags & NODE_IS_TARGET) 2230b94ba42SJung-uk Kim { 2240b94ba42SJung-uk Kim MethodInfo->LocalInitialized[RegisterNumber] = TRUE; 2250b94ba42SJung-uk Kim } 2260b94ba42SJung-uk Kim 2270b94ba42SJung-uk Kim /* 2280b94ba42SJung-uk Kim * Otherwise, this is a reference, check if the local 2290b94ba42SJung-uk Kim * has been previously initialized. 2300b94ba42SJung-uk Kim * 2310b94ba42SJung-uk Kim * The only operator that accepts an uninitialized value is ObjectType() 2320b94ba42SJung-uk Kim */ 2330b94ba42SJung-uk Kim else if ((!MethodInfo->LocalInitialized[RegisterNumber]) && 2340b94ba42SJung-uk Kim (Op->Asl.Parent->Asl.ParseOpcode != PARSEOP_OBJECTTYPE)) 2350b94ba42SJung-uk Kim { 2360b94ba42SJung-uk Kim LocalName[strlen (LocalName) -1] = (char) (RegisterNumber + 0x30); 2370b94ba42SJung-uk Kim AslError (ASL_ERROR, ASL_MSG_LOCAL_INIT, Op, LocalName); 2380b94ba42SJung-uk Kim } 2390b94ba42SJung-uk Kim break; 2400b94ba42SJung-uk Kim 2410b94ba42SJung-uk Kim 2420b94ba42SJung-uk Kim case PARSEOP_ARG0: 2430b94ba42SJung-uk Kim case PARSEOP_ARG1: 2440b94ba42SJung-uk Kim case PARSEOP_ARG2: 2450b94ba42SJung-uk Kim case PARSEOP_ARG3: 2460b94ba42SJung-uk Kim case PARSEOP_ARG4: 2470b94ba42SJung-uk Kim case PARSEOP_ARG5: 2480b94ba42SJung-uk Kim case PARSEOP_ARG6: 2490b94ba42SJung-uk Kim 2500b94ba42SJung-uk Kim if (!MethodInfo) 2510b94ba42SJung-uk Kim { 2520b94ba42SJung-uk Kim /* 2530b94ba42SJung-uk Kim * Arg was used outside a control method, or there was an error 2540b94ba42SJung-uk Kim * in the method declaration. 2550b94ba42SJung-uk Kim */ 2560b94ba42SJung-uk Kim AslError (ASL_REMARK, ASL_MSG_LOCAL_OUTSIDE_METHOD, Op, Op->Asl.ExternalName); 2570b94ba42SJung-uk Kim return (AE_ERROR); 2580b94ba42SJung-uk Kim } 2590b94ba42SJung-uk Kim 2600b94ba42SJung-uk Kim RegisterNumber = (Op->Asl.AmlOpcode & 0x000F) - 8; 2610b94ba42SJung-uk Kim ArgName[strlen (ArgName) -1] = (char) (RegisterNumber + 0x30); 2620b94ba42SJung-uk Kim 2630b94ba42SJung-uk Kim /* 2640b94ba42SJung-uk Kim * If the Arg is being used as a target, mark the local 2650b94ba42SJung-uk Kim * initialized 2660b94ba42SJung-uk Kim */ 2670b94ba42SJung-uk Kim if (Op->Asl.CompileFlags & NODE_IS_TARGET) 2680b94ba42SJung-uk Kim { 2690b94ba42SJung-uk Kim MethodInfo->ArgInitialized[RegisterNumber] = TRUE; 2700b94ba42SJung-uk Kim } 2710b94ba42SJung-uk Kim 2720b94ba42SJung-uk Kim /* 2730b94ba42SJung-uk Kim * Otherwise, this is a reference, check if the Arg 2740b94ba42SJung-uk Kim * has been previously initialized. 2750b94ba42SJung-uk Kim * 2760b94ba42SJung-uk Kim * The only operator that accepts an uninitialized value is ObjectType() 2770b94ba42SJung-uk Kim */ 2780b94ba42SJung-uk Kim else if ((!MethodInfo->ArgInitialized[RegisterNumber]) && 2790b94ba42SJung-uk Kim (Op->Asl.Parent->Asl.ParseOpcode != PARSEOP_OBJECTTYPE)) 2800b94ba42SJung-uk Kim { 2810b94ba42SJung-uk Kim AslError (ASL_ERROR, ASL_MSG_ARG_INIT, Op, ArgName); 2820b94ba42SJung-uk Kim } 2830b94ba42SJung-uk Kim 2840b94ba42SJung-uk Kim /* Flag this arg if it is not a "real" argument to the method */ 2850b94ba42SJung-uk Kim 2860b94ba42SJung-uk Kim if (RegisterNumber >= MethodInfo->NumArguments) 2870b94ba42SJung-uk Kim { 2880b94ba42SJung-uk Kim AslError (ASL_REMARK, ASL_MSG_NOT_PARAMETER, Op, ArgName); 2890b94ba42SJung-uk Kim } 2900b94ba42SJung-uk Kim break; 2910b94ba42SJung-uk Kim 2920b94ba42SJung-uk Kim 2930b94ba42SJung-uk Kim case PARSEOP_RETURN: 2940b94ba42SJung-uk Kim 2950b94ba42SJung-uk Kim if (!MethodInfo) 2960b94ba42SJung-uk Kim { 2970b94ba42SJung-uk Kim /* 2980b94ba42SJung-uk Kim * Probably was an error in the method declaration, 2990b94ba42SJung-uk Kim * no additional error here 3000b94ba42SJung-uk Kim */ 3010b94ba42SJung-uk Kim ACPI_WARNING ((AE_INFO, "%p, No parent method", Op)); 3020b94ba42SJung-uk Kim return (AE_ERROR); 3030b94ba42SJung-uk Kim } 3040b94ba42SJung-uk Kim 305d052a1ccSJung-uk Kim /* 306d052a1ccSJung-uk Kim * A child indicates a possible return value. A simple Return or 307d052a1ccSJung-uk Kim * Return() is marked with NODE_IS_NULL_RETURN by the parser so 308d052a1ccSJung-uk Kim * that it is not counted as a "real" return-with-value, although 309d052a1ccSJung-uk Kim * the AML code that is actually emitted is Return(0). The AML 310d052a1ccSJung-uk Kim * definition of Return has a required parameter, so we are 311d052a1ccSJung-uk Kim * forced to convert a null return to Return(0). 312d052a1ccSJung-uk Kim */ 3130b94ba42SJung-uk Kim if ((Op->Asl.Child) && 314d052a1ccSJung-uk Kim (Op->Asl.Child->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG) && 315d052a1ccSJung-uk Kim (!(Op->Asl.Child->Asl.CompileFlags & NODE_IS_NULL_RETURN))) 3160b94ba42SJung-uk Kim { 3170b94ba42SJung-uk Kim MethodInfo->NumReturnWithValue++; 3180b94ba42SJung-uk Kim } 3190b94ba42SJung-uk Kim else 3200b94ba42SJung-uk Kim { 3210b94ba42SJung-uk Kim MethodInfo->NumReturnNoValue++; 3220b94ba42SJung-uk Kim } 3230b94ba42SJung-uk Kim break; 3240b94ba42SJung-uk Kim 3250b94ba42SJung-uk Kim 3260b94ba42SJung-uk Kim case PARSEOP_BREAK: 3270b94ba42SJung-uk Kim case PARSEOP_CONTINUE: 3280b94ba42SJung-uk Kim 3290b94ba42SJung-uk Kim Next = Op->Asl.Parent; 3300b94ba42SJung-uk Kim while (Next) 3310b94ba42SJung-uk Kim { 3320b94ba42SJung-uk Kim if (Next->Asl.ParseOpcode == PARSEOP_WHILE) 3330b94ba42SJung-uk Kim { 3340b94ba42SJung-uk Kim break; 3350b94ba42SJung-uk Kim } 3360b94ba42SJung-uk Kim Next = Next->Asl.Parent; 3370b94ba42SJung-uk Kim } 3380b94ba42SJung-uk Kim 3390b94ba42SJung-uk Kim if (!Next) 3400b94ba42SJung-uk Kim { 3410b94ba42SJung-uk Kim AslError (ASL_ERROR, ASL_MSG_NO_WHILE, Op, NULL); 3420b94ba42SJung-uk Kim } 3430b94ba42SJung-uk Kim break; 3440b94ba42SJung-uk Kim 3450b94ba42SJung-uk Kim 3460b94ba42SJung-uk Kim case PARSEOP_STALL: 3470b94ba42SJung-uk Kim 3480b94ba42SJung-uk Kim /* We can range check if the argument is an integer */ 3490b94ba42SJung-uk Kim 3500b94ba42SJung-uk Kim if ((Op->Asl.Child->Asl.ParseOpcode == PARSEOP_INTEGER) && 3510b94ba42SJung-uk Kim (Op->Asl.Child->Asl.Value.Integer > ACPI_UINT8_MAX)) 3520b94ba42SJung-uk Kim { 3530b94ba42SJung-uk Kim AslError (ASL_ERROR, ASL_MSG_INVALID_TIME, Op, NULL); 3540b94ba42SJung-uk Kim } 3550b94ba42SJung-uk Kim break; 3560b94ba42SJung-uk Kim 3570b94ba42SJung-uk Kim 3580b94ba42SJung-uk Kim case PARSEOP_DEVICE: 3590b94ba42SJung-uk Kim case PARSEOP_EVENT: 3600b94ba42SJung-uk Kim case PARSEOP_MUTEX: 3610b94ba42SJung-uk Kim case PARSEOP_OPERATIONREGION: 3620b94ba42SJung-uk Kim case PARSEOP_POWERRESOURCE: 3630b94ba42SJung-uk Kim case PARSEOP_PROCESSOR: 3640b94ba42SJung-uk Kim case PARSEOP_THERMALZONE: 3650b94ba42SJung-uk Kim 3660b94ba42SJung-uk Kim /* 3670b94ba42SJung-uk Kim * The first operand is a name to be created in the namespace. 3680b94ba42SJung-uk Kim * Check against the reserved list. 3690b94ba42SJung-uk Kim */ 3700b94ba42SJung-uk Kim i = ApCheckForPredefinedName (Op, Op->Asl.NameSeg); 3710b94ba42SJung-uk Kim if (i < ACPI_VALID_RESERVED_NAME_MAX) 3720b94ba42SJung-uk Kim { 3730b94ba42SJung-uk Kim AslError (ASL_ERROR, ASL_MSG_RESERVED_USE, Op, Op->Asl.ExternalName); 3740b94ba42SJung-uk Kim } 3750b94ba42SJung-uk Kim break; 3760b94ba42SJung-uk Kim 3770b94ba42SJung-uk Kim 3780b94ba42SJung-uk Kim case PARSEOP_NAME: 3790b94ba42SJung-uk Kim 3800b94ba42SJung-uk Kim /* Typecheck any predefined names statically defined with Name() */ 3810b94ba42SJung-uk Kim 3820b94ba42SJung-uk Kim ApCheckForPredefinedObject (Op, Op->Asl.NameSeg); 3830b94ba42SJung-uk Kim 3840b94ba42SJung-uk Kim /* Special typechecking for _HID */ 3850b94ba42SJung-uk Kim 3860b94ba42SJung-uk Kim if (!ACPI_STRCMP (METHOD_NAME__HID, Op->Asl.NameSeg)) 3870b94ba42SJung-uk Kim { 3880b94ba42SJung-uk Kim Next = Op->Asl.Child->Asl.Next; 3890b94ba42SJung-uk Kim AnCheckId (Next, ASL_TYPE_HID); 3900b94ba42SJung-uk Kim } 3910b94ba42SJung-uk Kim 3920b94ba42SJung-uk Kim /* Special typechecking for _CID */ 3930b94ba42SJung-uk Kim 3940b94ba42SJung-uk Kim else if (!ACPI_STRCMP (METHOD_NAME__CID, Op->Asl.NameSeg)) 3950b94ba42SJung-uk Kim { 3960b94ba42SJung-uk Kim Next = Op->Asl.Child->Asl.Next; 3970b94ba42SJung-uk Kim 3980b94ba42SJung-uk Kim if ((Next->Asl.ParseOpcode == PARSEOP_PACKAGE) || 3990b94ba42SJung-uk Kim (Next->Asl.ParseOpcode == PARSEOP_VAR_PACKAGE)) 4000b94ba42SJung-uk Kim { 4010b94ba42SJung-uk Kim Next = Next->Asl.Child; 4020b94ba42SJung-uk Kim while (Next) 4030b94ba42SJung-uk Kim { 4040b94ba42SJung-uk Kim AnCheckId (Next, ASL_TYPE_CID); 4050b94ba42SJung-uk Kim Next = Next->Asl.Next; 4060b94ba42SJung-uk Kim } 4070b94ba42SJung-uk Kim } 4080b94ba42SJung-uk Kim else 4090b94ba42SJung-uk Kim { 4100b94ba42SJung-uk Kim AnCheckId (Next, ASL_TYPE_CID); 4110b94ba42SJung-uk Kim } 4120b94ba42SJung-uk Kim } 4130b94ba42SJung-uk Kim break; 4140b94ba42SJung-uk Kim 4150b94ba42SJung-uk Kim 4160b94ba42SJung-uk Kim default: 4170b94ba42SJung-uk Kim break; 4180b94ba42SJung-uk Kim } 4190b94ba42SJung-uk Kim 4200b94ba42SJung-uk Kim return (AE_OK); 4210b94ba42SJung-uk Kim } 4220b94ba42SJung-uk Kim 4230b94ba42SJung-uk Kim 4240b94ba42SJung-uk Kim /******************************************************************************* 4250b94ba42SJung-uk Kim * 4260b94ba42SJung-uk Kim * FUNCTION: AnMethodAnalysisWalkEnd 4270b94ba42SJung-uk Kim * 4280b94ba42SJung-uk Kim * PARAMETERS: ASL_WALK_CALLBACK 4290b94ba42SJung-uk Kim * 4300b94ba42SJung-uk Kim * RETURN: Status 4310b94ba42SJung-uk Kim * 4320b94ba42SJung-uk Kim * DESCRIPTION: Ascending callback for analysis walk. Complete method 4330b94ba42SJung-uk Kim * return analysis. 4340b94ba42SJung-uk Kim * 4350b94ba42SJung-uk Kim ******************************************************************************/ 4360b94ba42SJung-uk Kim 4370b94ba42SJung-uk Kim ACPI_STATUS 4380b94ba42SJung-uk Kim AnMethodAnalysisWalkEnd ( 4390b94ba42SJung-uk Kim ACPI_PARSE_OBJECT *Op, 4400b94ba42SJung-uk Kim UINT32 Level, 4410b94ba42SJung-uk Kim void *Context) 4420b94ba42SJung-uk Kim { 4430b94ba42SJung-uk Kim ASL_ANALYSIS_WALK_INFO *WalkInfo = (ASL_ANALYSIS_WALK_INFO *) Context; 4440b94ba42SJung-uk Kim ASL_METHOD_INFO *MethodInfo = WalkInfo->MethodStack; 4450b94ba42SJung-uk Kim 4460b94ba42SJung-uk Kim 4470b94ba42SJung-uk Kim switch (Op->Asl.ParseOpcode) 4480b94ba42SJung-uk Kim { 4490b94ba42SJung-uk Kim case PARSEOP_METHOD: 4500b94ba42SJung-uk Kim case PARSEOP_RETURN: 4510b94ba42SJung-uk Kim if (!MethodInfo) 4520b94ba42SJung-uk Kim { 4530b94ba42SJung-uk Kim printf ("No method info for method! [%s]\n", Op->Asl.Namepath); 4540b94ba42SJung-uk Kim AslError (ASL_ERROR, ASL_MSG_COMPILER_INTERNAL, Op, 4550b94ba42SJung-uk Kim "No method info for this method"); 4560b94ba42SJung-uk Kim 4570b94ba42SJung-uk Kim CmCleanupAndExit (); 4580b94ba42SJung-uk Kim return (AE_AML_INTERNAL); 4590b94ba42SJung-uk Kim } 4600b94ba42SJung-uk Kim break; 4610b94ba42SJung-uk Kim 4620b94ba42SJung-uk Kim default: 4630b94ba42SJung-uk Kim break; 4640b94ba42SJung-uk Kim } 4650b94ba42SJung-uk Kim 4660b94ba42SJung-uk Kim switch (Op->Asl.ParseOpcode) 4670b94ba42SJung-uk Kim { 4680b94ba42SJung-uk Kim case PARSEOP_METHOD: 4690b94ba42SJung-uk Kim 4700b94ba42SJung-uk Kim WalkInfo->MethodStack = MethodInfo->Next; 4710b94ba42SJung-uk Kim 4720b94ba42SJung-uk Kim /* 4730b94ba42SJung-uk Kim * Check if there is no return statement at the end of the 4740b94ba42SJung-uk Kim * method AND we can actually get there -- i.e., the execution 4750b94ba42SJung-uk Kim * of the method can possibly terminate without a return statement. 4760b94ba42SJung-uk Kim */ 4770b94ba42SJung-uk Kim if ((!AnLastStatementIsReturn (Op)) && 4780b94ba42SJung-uk Kim (!(Op->Asl.CompileFlags & NODE_HAS_NO_EXIT))) 4790b94ba42SJung-uk Kim { 4800b94ba42SJung-uk Kim /* 4810b94ba42SJung-uk Kim * No return statement, and execution can possibly exit 4820b94ba42SJung-uk Kim * via this path. This is equivalent to Return () 4830b94ba42SJung-uk Kim */ 4840b94ba42SJung-uk Kim MethodInfo->NumReturnNoValue++; 4850b94ba42SJung-uk Kim } 4860b94ba42SJung-uk Kim 4870b94ba42SJung-uk Kim /* 4880b94ba42SJung-uk Kim * Check for case where some return statements have a return value 4890b94ba42SJung-uk Kim * and some do not. Exit without a return statement is a return with 4900b94ba42SJung-uk Kim * no value 4910b94ba42SJung-uk Kim */ 4920b94ba42SJung-uk Kim if (MethodInfo->NumReturnNoValue && 4930b94ba42SJung-uk Kim MethodInfo->NumReturnWithValue) 4940b94ba42SJung-uk Kim { 4950b94ba42SJung-uk Kim AslError (ASL_WARNING, ASL_MSG_RETURN_TYPES, Op, 4960b94ba42SJung-uk Kim Op->Asl.ExternalName); 4970b94ba42SJung-uk Kim } 4980b94ba42SJung-uk Kim 4990b94ba42SJung-uk Kim /* 5000b94ba42SJung-uk Kim * If there are any RETURN() statements with no value, or there is a 5010b94ba42SJung-uk Kim * control path that allows the method to exit without a return value, 5020b94ba42SJung-uk Kim * we mark the method as a method that does not return a value. This 5030b94ba42SJung-uk Kim * knowledge can be used to check method invocations that expect a 5040b94ba42SJung-uk Kim * returned value. 5050b94ba42SJung-uk Kim */ 5060b94ba42SJung-uk Kim if (MethodInfo->NumReturnNoValue) 5070b94ba42SJung-uk Kim { 5080b94ba42SJung-uk Kim if (MethodInfo->NumReturnWithValue) 5090b94ba42SJung-uk Kim { 5100b94ba42SJung-uk Kim Op->Asl.CompileFlags |= NODE_METHOD_SOME_NO_RETVAL; 5110b94ba42SJung-uk Kim } 5120b94ba42SJung-uk Kim else 5130b94ba42SJung-uk Kim { 5140b94ba42SJung-uk Kim Op->Asl.CompileFlags |= NODE_METHOD_NO_RETVAL; 5150b94ba42SJung-uk Kim } 5160b94ba42SJung-uk Kim } 5170b94ba42SJung-uk Kim 5180b94ba42SJung-uk Kim /* 5190b94ba42SJung-uk Kim * Check predefined method names for correct return behavior 520d052a1ccSJung-uk Kim * and correct number of arguments. Also, some special checks 521d052a1ccSJung-uk Kim * For GPE and _REG methods. 5220b94ba42SJung-uk Kim */ 523d052a1ccSJung-uk Kim if (ApCheckForPredefinedMethod (Op, MethodInfo)) 524d052a1ccSJung-uk Kim { 5250b94ba42SJung-uk Kim /* Special check for two names like _L01 and _E01 in same scope */ 5260b94ba42SJung-uk Kim 5270b94ba42SJung-uk Kim ApCheckForGpeNameConflict (Op); 528d052a1ccSJung-uk Kim 529d052a1ccSJung-uk Kim /* 530d052a1ccSJung-uk Kim * Special check for _REG: Must have an operation region definition 531d052a1ccSJung-uk Kim * within the same scope! 532d052a1ccSJung-uk Kim */ 533d052a1ccSJung-uk Kim ApCheckRegMethod (Op); 534d052a1ccSJung-uk Kim } 535d052a1ccSJung-uk Kim 5360b94ba42SJung-uk Kim ACPI_FREE (MethodInfo); 5370b94ba42SJung-uk Kim break; 5380b94ba42SJung-uk Kim 5390b94ba42SJung-uk Kim 5400b94ba42SJung-uk Kim case PARSEOP_NAME: 5410b94ba42SJung-uk Kim 5420b94ba42SJung-uk Kim /* Special check for two names like _L01 and _E01 in same scope */ 5430b94ba42SJung-uk Kim 5440b94ba42SJung-uk Kim ApCheckForGpeNameConflict (Op); 5450b94ba42SJung-uk Kim break; 5460b94ba42SJung-uk Kim 5470b94ba42SJung-uk Kim 5480b94ba42SJung-uk Kim case PARSEOP_RETURN: 5490b94ba42SJung-uk Kim 5500b94ba42SJung-uk Kim /* 5510b94ba42SJung-uk Kim * If the parent is a predefined method name, attempt to typecheck 5520b94ba42SJung-uk Kim * the return value. Only static types can be validated. 5530b94ba42SJung-uk Kim */ 5540b94ba42SJung-uk Kim ApCheckPredefinedReturnValue (Op, MethodInfo); 5550b94ba42SJung-uk Kim 5560b94ba42SJung-uk Kim /* 5570b94ba42SJung-uk Kim * The parent block does not "exit" and continue execution -- the 5580b94ba42SJung-uk Kim * method is terminated here with the Return() statement. 5590b94ba42SJung-uk Kim */ 5600b94ba42SJung-uk Kim Op->Asl.Parent->Asl.CompileFlags |= NODE_HAS_NO_EXIT; 5610b94ba42SJung-uk Kim 5620b94ba42SJung-uk Kim /* Used in the "typing" pass later */ 5630b94ba42SJung-uk Kim 5640b94ba42SJung-uk Kim Op->Asl.ParentMethod = MethodInfo->Op; 5650b94ba42SJung-uk Kim 5660b94ba42SJung-uk Kim /* 5670b94ba42SJung-uk Kim * If there is a peer node after the return statement, then this 5680b94ba42SJung-uk Kim * node is unreachable code -- i.e., it won't be executed because of 5690b94ba42SJung-uk Kim * the preceeding Return() statement. 5700b94ba42SJung-uk Kim */ 5710b94ba42SJung-uk Kim if (Op->Asl.Next) 5720b94ba42SJung-uk Kim { 5730b94ba42SJung-uk Kim AslError (ASL_WARNING, ASL_MSG_UNREACHABLE_CODE, Op->Asl.Next, NULL); 5740b94ba42SJung-uk Kim } 5750b94ba42SJung-uk Kim break; 5760b94ba42SJung-uk Kim 5770b94ba42SJung-uk Kim 5780b94ba42SJung-uk Kim case PARSEOP_IF: 5790b94ba42SJung-uk Kim 5800b94ba42SJung-uk Kim if ((Op->Asl.CompileFlags & NODE_HAS_NO_EXIT) && 5810b94ba42SJung-uk Kim (Op->Asl.Next) && 5820b94ba42SJung-uk Kim (Op->Asl.Next->Asl.ParseOpcode == PARSEOP_ELSE)) 5830b94ba42SJung-uk Kim { 5840b94ba42SJung-uk Kim /* 5850b94ba42SJung-uk Kim * This IF has a corresponding ELSE. The IF block has no exit, 5860b94ba42SJung-uk Kim * (it contains an unconditional Return) 5870b94ba42SJung-uk Kim * mark the ELSE block to remember this fact. 5880b94ba42SJung-uk Kim */ 5890b94ba42SJung-uk Kim Op->Asl.Next->Asl.CompileFlags |= NODE_IF_HAS_NO_EXIT; 5900b94ba42SJung-uk Kim } 5910b94ba42SJung-uk Kim break; 5920b94ba42SJung-uk Kim 5930b94ba42SJung-uk Kim 5940b94ba42SJung-uk Kim case PARSEOP_ELSE: 5950b94ba42SJung-uk Kim 5960b94ba42SJung-uk Kim if ((Op->Asl.CompileFlags & NODE_HAS_NO_EXIT) && 5970b94ba42SJung-uk Kim (Op->Asl.CompileFlags & NODE_IF_HAS_NO_EXIT)) 5980b94ba42SJung-uk Kim { 5990b94ba42SJung-uk Kim /* 6000b94ba42SJung-uk Kim * This ELSE block has no exit and the corresponding IF block 6010b94ba42SJung-uk Kim * has no exit either. Therefore, the parent node has no exit. 6020b94ba42SJung-uk Kim */ 6030b94ba42SJung-uk Kim Op->Asl.Parent->Asl.CompileFlags |= NODE_HAS_NO_EXIT; 6040b94ba42SJung-uk Kim } 6050b94ba42SJung-uk Kim break; 6060b94ba42SJung-uk Kim 6070b94ba42SJung-uk Kim 6080b94ba42SJung-uk Kim default: 6090b94ba42SJung-uk Kim 6100b94ba42SJung-uk Kim if ((Op->Asl.CompileFlags & NODE_HAS_NO_EXIT) && 6110b94ba42SJung-uk Kim (Op->Asl.Parent)) 6120b94ba42SJung-uk Kim { 6130b94ba42SJung-uk Kim /* If this node has no exit, then the parent has no exit either */ 6140b94ba42SJung-uk Kim 6150b94ba42SJung-uk Kim Op->Asl.Parent->Asl.CompileFlags |= NODE_HAS_NO_EXIT; 6160b94ba42SJung-uk Kim } 6170b94ba42SJung-uk Kim break; 6180b94ba42SJung-uk Kim } 6190b94ba42SJung-uk Kim 6200b94ba42SJung-uk Kim return (AE_OK); 6210b94ba42SJung-uk Kim } 6220b94ba42SJung-uk Kim 6230b94ba42SJung-uk Kim 6240b94ba42SJung-uk Kim /******************************************************************************* 6250b94ba42SJung-uk Kim * 6260b94ba42SJung-uk Kim * FUNCTION: AnMethodTypingWalkEnd 6270b94ba42SJung-uk Kim * 6280b94ba42SJung-uk Kim * PARAMETERS: ASL_WALK_CALLBACK 6290b94ba42SJung-uk Kim * 6300b94ba42SJung-uk Kim * RETURN: Status 6310b94ba42SJung-uk Kim * 6320b94ba42SJung-uk Kim * DESCRIPTION: Ascending callback for typing walk. Complete the method 6330b94ba42SJung-uk Kim * return analysis. Check methods for: 6340b94ba42SJung-uk Kim * 1) Initialized local variables 6350b94ba42SJung-uk Kim * 2) Valid arguments 6360b94ba42SJung-uk Kim * 3) Return types 6370b94ba42SJung-uk Kim * 6380b94ba42SJung-uk Kim ******************************************************************************/ 6390b94ba42SJung-uk Kim 6400b94ba42SJung-uk Kim ACPI_STATUS 6410b94ba42SJung-uk Kim AnMethodTypingWalkEnd ( 6420b94ba42SJung-uk Kim ACPI_PARSE_OBJECT *Op, 6430b94ba42SJung-uk Kim UINT32 Level, 6440b94ba42SJung-uk Kim void *Context) 6450b94ba42SJung-uk Kim { 6460b94ba42SJung-uk Kim UINT32 ThisNodeBtype; 6470b94ba42SJung-uk Kim 6480b94ba42SJung-uk Kim 6490b94ba42SJung-uk Kim switch (Op->Asl.ParseOpcode) 6500b94ba42SJung-uk Kim { 6510b94ba42SJung-uk Kim case PARSEOP_METHOD: 6520b94ba42SJung-uk Kim 6530b94ba42SJung-uk Kim Op->Asl.CompileFlags |= NODE_METHOD_TYPED; 6540b94ba42SJung-uk Kim break; 6550b94ba42SJung-uk Kim 6560b94ba42SJung-uk Kim case PARSEOP_RETURN: 6570b94ba42SJung-uk Kim 6580b94ba42SJung-uk Kim if ((Op->Asl.Child) && 6590b94ba42SJung-uk Kim (Op->Asl.Child->Asl.ParseOpcode != PARSEOP_DEFAULT_ARG)) 6600b94ba42SJung-uk Kim { 6610b94ba42SJung-uk Kim ThisNodeBtype = AnGetBtype (Op->Asl.Child); 6620b94ba42SJung-uk Kim 6630b94ba42SJung-uk Kim if ((Op->Asl.Child->Asl.ParseOpcode == PARSEOP_METHODCALL) && 6640b94ba42SJung-uk Kim (ThisNodeBtype == (ACPI_UINT32_MAX -1))) 6650b94ba42SJung-uk Kim { 6660b94ba42SJung-uk Kim /* 6670b94ba42SJung-uk Kim * The called method is untyped at this time (typically a 6680b94ba42SJung-uk Kim * forward reference). 6690b94ba42SJung-uk Kim * 6700b94ba42SJung-uk Kim * Check for a recursive method call first. 6710b94ba42SJung-uk Kim */ 6720b94ba42SJung-uk Kim if (Op->Asl.ParentMethod != Op->Asl.Child->Asl.Node->Op) 6730b94ba42SJung-uk Kim { 6740b94ba42SJung-uk Kim /* We must type the method here */ 6750b94ba42SJung-uk Kim 6760b94ba42SJung-uk Kim TrWalkParseTree (Op->Asl.Child->Asl.Node->Op, 6770b94ba42SJung-uk Kim ASL_WALK_VISIT_UPWARD, NULL, 6780b94ba42SJung-uk Kim AnMethodTypingWalkEnd, NULL); 6790b94ba42SJung-uk Kim 6800b94ba42SJung-uk Kim ThisNodeBtype = AnGetBtype (Op->Asl.Child); 6810b94ba42SJung-uk Kim } 6820b94ba42SJung-uk Kim } 6830b94ba42SJung-uk Kim 6840b94ba42SJung-uk Kim /* Returns a value, save the value type */ 6850b94ba42SJung-uk Kim 6860b94ba42SJung-uk Kim if (Op->Asl.ParentMethod) 6870b94ba42SJung-uk Kim { 6880b94ba42SJung-uk Kim Op->Asl.ParentMethod->Asl.AcpiBtype |= ThisNodeBtype; 6890b94ba42SJung-uk Kim } 6900b94ba42SJung-uk Kim } 6910b94ba42SJung-uk Kim break; 6920b94ba42SJung-uk Kim 6930b94ba42SJung-uk Kim default: 6940b94ba42SJung-uk Kim break; 6950b94ba42SJung-uk Kim } 6960b94ba42SJung-uk Kim 6970b94ba42SJung-uk Kim return (AE_OK); 6980b94ba42SJung-uk Kim } 6990b94ba42SJung-uk Kim 7000b94ba42SJung-uk Kim 7010b94ba42SJung-uk Kim /******************************************************************************* 7020b94ba42SJung-uk Kim * 7030b94ba42SJung-uk Kim * FUNCTION: AnOperandTypecheckWalkEnd 7040b94ba42SJung-uk Kim * 7050b94ba42SJung-uk Kim * PARAMETERS: ASL_WALK_CALLBACK 7060b94ba42SJung-uk Kim * 7070b94ba42SJung-uk Kim * RETURN: Status 7080b94ba42SJung-uk Kim * 7090b94ba42SJung-uk Kim * DESCRIPTION: Ascending callback for analysis walk. Complete method 7100b94ba42SJung-uk Kim * return analysis. 7110b94ba42SJung-uk Kim * 7120b94ba42SJung-uk Kim ******************************************************************************/ 7130b94ba42SJung-uk Kim 7140b94ba42SJung-uk Kim ACPI_STATUS 7150b94ba42SJung-uk Kim AnOperandTypecheckWalkEnd ( 7160b94ba42SJung-uk Kim ACPI_PARSE_OBJECT *Op, 7170b94ba42SJung-uk Kim UINT32 Level, 7180b94ba42SJung-uk Kim void *Context) 7190b94ba42SJung-uk Kim { 7200b94ba42SJung-uk Kim const ACPI_OPCODE_INFO *OpInfo; 7210b94ba42SJung-uk Kim UINT32 RuntimeArgTypes; 7220b94ba42SJung-uk Kim UINT32 RuntimeArgTypes2; 7230b94ba42SJung-uk Kim UINT32 RequiredBtypes; 7240b94ba42SJung-uk Kim UINT32 ThisNodeBtype; 7250b94ba42SJung-uk Kim UINT32 CommonBtypes; 7260b94ba42SJung-uk Kim UINT32 OpcodeClass; 7270b94ba42SJung-uk Kim ACPI_PARSE_OBJECT *ArgOp; 7280b94ba42SJung-uk Kim UINT32 ArgType; 7290b94ba42SJung-uk Kim 7300b94ba42SJung-uk Kim 7310b94ba42SJung-uk Kim switch (Op->Asl.AmlOpcode) 7320b94ba42SJung-uk Kim { 7330b94ba42SJung-uk Kim case AML_RAW_DATA_BYTE: 7340b94ba42SJung-uk Kim case AML_RAW_DATA_WORD: 7350b94ba42SJung-uk Kim case AML_RAW_DATA_DWORD: 7360b94ba42SJung-uk Kim case AML_RAW_DATA_QWORD: 7370b94ba42SJung-uk Kim case AML_RAW_DATA_BUFFER: 7380b94ba42SJung-uk Kim case AML_RAW_DATA_CHAIN: 7390b94ba42SJung-uk Kim case AML_PACKAGE_LENGTH: 7400b94ba42SJung-uk Kim case AML_UNASSIGNED_OPCODE: 7410b94ba42SJung-uk Kim case AML_DEFAULT_ARG_OP: 7420b94ba42SJung-uk Kim 7430b94ba42SJung-uk Kim /* Ignore the internal (compiler-only) AML opcodes */ 7440b94ba42SJung-uk Kim 7450b94ba42SJung-uk Kim return (AE_OK); 7460b94ba42SJung-uk Kim 7470b94ba42SJung-uk Kim default: 7480b94ba42SJung-uk Kim break; 7490b94ba42SJung-uk Kim } 7500b94ba42SJung-uk Kim 7510b94ba42SJung-uk Kim OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode); 7520b94ba42SJung-uk Kim if (!OpInfo) 7530b94ba42SJung-uk Kim { 7540b94ba42SJung-uk Kim return (AE_OK); 7550b94ba42SJung-uk Kim } 7560b94ba42SJung-uk Kim 7570b94ba42SJung-uk Kim ArgOp = Op->Asl.Child; 7580b94ba42SJung-uk Kim RuntimeArgTypes = OpInfo->RuntimeArgs; 7590b94ba42SJung-uk Kim OpcodeClass = OpInfo->Class; 7600b94ba42SJung-uk Kim 7610b94ba42SJung-uk Kim #ifdef ASL_ERROR_NAMED_OBJECT_IN_WHILE 7620b94ba42SJung-uk Kim /* 7630b94ba42SJung-uk Kim * Update 11/2008: In practice, we can't perform this check. A simple 7640b94ba42SJung-uk Kim * analysis is not sufficient. Also, it can cause errors when compiling 7650b94ba42SJung-uk Kim * disassembled code because of the way Switch operators are implemented 7660b94ba42SJung-uk Kim * (a While(One) loop with a named temp variable created within.) 7670b94ba42SJung-uk Kim */ 7680b94ba42SJung-uk Kim 7690b94ba42SJung-uk Kim /* 7700b94ba42SJung-uk Kim * If we are creating a named object, check if we are within a while loop 7710b94ba42SJung-uk Kim * by checking if the parent is a WHILE op. This is a simple analysis, but 7720b94ba42SJung-uk Kim * probably sufficient for many cases. 7730b94ba42SJung-uk Kim * 7740b94ba42SJung-uk Kim * Allow Scope(), Buffer(), and Package(). 7750b94ba42SJung-uk Kim */ 7760b94ba42SJung-uk Kim if (((OpcodeClass == AML_CLASS_NAMED_OBJECT) && (Op->Asl.AmlOpcode != AML_SCOPE_OP)) || 7770b94ba42SJung-uk Kim ((OpcodeClass == AML_CLASS_CREATE) && (OpInfo->Flags & AML_NSNODE))) 7780b94ba42SJung-uk Kim { 7790b94ba42SJung-uk Kim if (Op->Asl.Parent->Asl.AmlOpcode == AML_WHILE_OP) 7800b94ba42SJung-uk Kim { 7810b94ba42SJung-uk Kim AslError (ASL_ERROR, ASL_MSG_NAMED_OBJECT_IN_WHILE, Op, NULL); 7820b94ba42SJung-uk Kim } 7830b94ba42SJung-uk Kim } 7840b94ba42SJung-uk Kim #endif 7850b94ba42SJung-uk Kim 7860b94ba42SJung-uk Kim /* 7870b94ba42SJung-uk Kim * Special case for control opcodes IF/RETURN/WHILE since they 7880b94ba42SJung-uk Kim * have no runtime arg list (at this time) 7890b94ba42SJung-uk Kim */ 7900b94ba42SJung-uk Kim switch (Op->Asl.AmlOpcode) 7910b94ba42SJung-uk Kim { 7920b94ba42SJung-uk Kim case AML_IF_OP: 7930b94ba42SJung-uk Kim case AML_WHILE_OP: 7940b94ba42SJung-uk Kim case AML_RETURN_OP: 7950b94ba42SJung-uk Kim 7960b94ba42SJung-uk Kim if (ArgOp->Asl.ParseOpcode == PARSEOP_METHODCALL) 7970b94ba42SJung-uk Kim { 7980b94ba42SJung-uk Kim /* Check for an internal method */ 7990b94ba42SJung-uk Kim 8000b94ba42SJung-uk Kim if (AnIsInternalMethod (ArgOp)) 8010b94ba42SJung-uk Kim { 8020b94ba42SJung-uk Kim return (AE_OK); 8030b94ba42SJung-uk Kim } 8040b94ba42SJung-uk Kim 8050b94ba42SJung-uk Kim /* The lone arg is a method call, check it */ 8060b94ba42SJung-uk Kim 8070b94ba42SJung-uk Kim RequiredBtypes = AnMapArgTypeToBtype (ARGI_INTEGER); 8080b94ba42SJung-uk Kim if (Op->Asl.AmlOpcode == AML_RETURN_OP) 8090b94ba42SJung-uk Kim { 8100b94ba42SJung-uk Kim RequiredBtypes = 0xFFFFFFFF; 8110b94ba42SJung-uk Kim } 8120b94ba42SJung-uk Kim 8130b94ba42SJung-uk Kim ThisNodeBtype = AnGetBtype (ArgOp); 8140b94ba42SJung-uk Kim if (ThisNodeBtype == ACPI_UINT32_MAX) 8150b94ba42SJung-uk Kim { 8160b94ba42SJung-uk Kim return (AE_OK); 8170b94ba42SJung-uk Kim } 8180b94ba42SJung-uk Kim AnCheckMethodReturnValue (Op, OpInfo, ArgOp, 8190b94ba42SJung-uk Kim RequiredBtypes, ThisNodeBtype); 8200b94ba42SJung-uk Kim } 8210b94ba42SJung-uk Kim return (AE_OK); 8220b94ba42SJung-uk Kim 8230b94ba42SJung-uk Kim default: 8240b94ba42SJung-uk Kim break; 8250b94ba42SJung-uk Kim } 8260b94ba42SJung-uk Kim 8270b94ba42SJung-uk Kim /* Ignore the non-executable opcodes */ 8280b94ba42SJung-uk Kim 8290b94ba42SJung-uk Kim if (RuntimeArgTypes == ARGI_INVALID_OPCODE) 8300b94ba42SJung-uk Kim { 8310b94ba42SJung-uk Kim return (AE_OK); 8320b94ba42SJung-uk Kim } 8330b94ba42SJung-uk Kim 8340b94ba42SJung-uk Kim switch (OpcodeClass) 8350b94ba42SJung-uk Kim { 8360b94ba42SJung-uk Kim case AML_CLASS_EXECUTE: 8370b94ba42SJung-uk Kim case AML_CLASS_CREATE: 8380b94ba42SJung-uk Kim case AML_CLASS_CONTROL: 8390b94ba42SJung-uk Kim case AML_CLASS_RETURN_VALUE: 8400b94ba42SJung-uk Kim 8410b94ba42SJung-uk Kim /* TBD: Change class or fix typechecking for these */ 8420b94ba42SJung-uk Kim 8430b94ba42SJung-uk Kim if ((Op->Asl.AmlOpcode == AML_BUFFER_OP) || 8440b94ba42SJung-uk Kim (Op->Asl.AmlOpcode == AML_PACKAGE_OP) || 8450b94ba42SJung-uk Kim (Op->Asl.AmlOpcode == AML_VAR_PACKAGE_OP)) 8460b94ba42SJung-uk Kim { 8470b94ba42SJung-uk Kim break; 8480b94ba42SJung-uk Kim } 8490b94ba42SJung-uk Kim 8500b94ba42SJung-uk Kim /* Reverse the runtime argument list */ 8510b94ba42SJung-uk Kim 8520b94ba42SJung-uk Kim RuntimeArgTypes2 = 0; 8530b94ba42SJung-uk Kim while ((ArgType = GET_CURRENT_ARG_TYPE (RuntimeArgTypes))) 8540b94ba42SJung-uk Kim { 8550b94ba42SJung-uk Kim RuntimeArgTypes2 <<= ARG_TYPE_WIDTH; 8560b94ba42SJung-uk Kim RuntimeArgTypes2 |= ArgType; 8570b94ba42SJung-uk Kim INCREMENT_ARG_LIST (RuntimeArgTypes); 8580b94ba42SJung-uk Kim } 8590b94ba42SJung-uk Kim 8600b94ba42SJung-uk Kim while ((ArgType = GET_CURRENT_ARG_TYPE (RuntimeArgTypes2))) 8610b94ba42SJung-uk Kim { 8620b94ba42SJung-uk Kim RequiredBtypes = AnMapArgTypeToBtype (ArgType); 8630b94ba42SJung-uk Kim 8640b94ba42SJung-uk Kim ThisNodeBtype = AnGetBtype (ArgOp); 8650b94ba42SJung-uk Kim if (ThisNodeBtype == ACPI_UINT32_MAX) 8660b94ba42SJung-uk Kim { 8670b94ba42SJung-uk Kim goto NextArgument; 8680b94ba42SJung-uk Kim } 8690b94ba42SJung-uk Kim 8700b94ba42SJung-uk Kim /* Examine the arg based on the required type of the arg */ 8710b94ba42SJung-uk Kim 8720b94ba42SJung-uk Kim switch (ArgType) 8730b94ba42SJung-uk Kim { 8740b94ba42SJung-uk Kim case ARGI_TARGETREF: 8750b94ba42SJung-uk Kim 8760b94ba42SJung-uk Kim if (ArgOp->Asl.ParseOpcode == PARSEOP_ZERO) 8770b94ba42SJung-uk Kim { 8780b94ba42SJung-uk Kim /* ZERO is the placeholder for "don't store result" */ 8790b94ba42SJung-uk Kim 8800b94ba42SJung-uk Kim ThisNodeBtype = RequiredBtypes; 8810b94ba42SJung-uk Kim break; 8820b94ba42SJung-uk Kim } 8830b94ba42SJung-uk Kim 8840b94ba42SJung-uk Kim if (ArgOp->Asl.ParseOpcode == PARSEOP_INTEGER) 8850b94ba42SJung-uk Kim { 8860b94ba42SJung-uk Kim /* 8870b94ba42SJung-uk Kim * This is the case where an original reference to a resource 8880b94ba42SJung-uk Kim * descriptor field has been replaced by an (Integer) offset. 8890b94ba42SJung-uk Kim * These named fields are supported at compile-time only; 8900b94ba42SJung-uk Kim * the names are not passed to the interpreter (via the AML). 8910b94ba42SJung-uk Kim */ 8920b94ba42SJung-uk Kim if ((ArgOp->Asl.Node->Type == ACPI_TYPE_LOCAL_RESOURCE_FIELD) || 8930b94ba42SJung-uk Kim (ArgOp->Asl.Node->Type == ACPI_TYPE_LOCAL_RESOURCE)) 8940b94ba42SJung-uk Kim { 8950b94ba42SJung-uk Kim AslError (ASL_ERROR, ASL_MSG_RESOURCE_FIELD, ArgOp, NULL); 8960b94ba42SJung-uk Kim } 8970b94ba42SJung-uk Kim else 8980b94ba42SJung-uk Kim { 8990b94ba42SJung-uk Kim AslError (ASL_ERROR, ASL_MSG_INVALID_TYPE, ArgOp, NULL); 9000b94ba42SJung-uk Kim } 9010b94ba42SJung-uk Kim break; 9020b94ba42SJung-uk Kim } 9030b94ba42SJung-uk Kim 9040b94ba42SJung-uk Kim if ((ArgOp->Asl.ParseOpcode == PARSEOP_METHODCALL) || 9050b94ba42SJung-uk Kim (ArgOp->Asl.ParseOpcode == PARSEOP_DEREFOF)) 9060b94ba42SJung-uk Kim { 9070b94ba42SJung-uk Kim break; 9080b94ba42SJung-uk Kim } 9090b94ba42SJung-uk Kim 9100b94ba42SJung-uk Kim ThisNodeBtype = RequiredBtypes; 9110b94ba42SJung-uk Kim break; 9120b94ba42SJung-uk Kim 9130b94ba42SJung-uk Kim 9140b94ba42SJung-uk Kim case ARGI_REFERENCE: /* References */ 9150b94ba42SJung-uk Kim case ARGI_INTEGER_REF: 9160b94ba42SJung-uk Kim case ARGI_OBJECT_REF: 9170b94ba42SJung-uk Kim case ARGI_DEVICE_REF: 9180b94ba42SJung-uk Kim 9190b94ba42SJung-uk Kim switch (ArgOp->Asl.ParseOpcode) 9200b94ba42SJung-uk Kim { 9210b94ba42SJung-uk Kim case PARSEOP_LOCAL0: 9220b94ba42SJung-uk Kim case PARSEOP_LOCAL1: 9230b94ba42SJung-uk Kim case PARSEOP_LOCAL2: 9240b94ba42SJung-uk Kim case PARSEOP_LOCAL3: 9250b94ba42SJung-uk Kim case PARSEOP_LOCAL4: 9260b94ba42SJung-uk Kim case PARSEOP_LOCAL5: 9270b94ba42SJung-uk Kim case PARSEOP_LOCAL6: 9280b94ba42SJung-uk Kim case PARSEOP_LOCAL7: 9290b94ba42SJung-uk Kim 9300b94ba42SJung-uk Kim /* TBD: implement analysis of current value (type) of the local */ 9310b94ba42SJung-uk Kim /* For now, just treat any local as a typematch */ 9320b94ba42SJung-uk Kim 9330b94ba42SJung-uk Kim /*ThisNodeBtype = RequiredBtypes;*/ 9340b94ba42SJung-uk Kim break; 9350b94ba42SJung-uk Kim 9360b94ba42SJung-uk Kim case PARSEOP_ARG0: 9370b94ba42SJung-uk Kim case PARSEOP_ARG1: 9380b94ba42SJung-uk Kim case PARSEOP_ARG2: 9390b94ba42SJung-uk Kim case PARSEOP_ARG3: 9400b94ba42SJung-uk Kim case PARSEOP_ARG4: 9410b94ba42SJung-uk Kim case PARSEOP_ARG5: 9420b94ba42SJung-uk Kim case PARSEOP_ARG6: 9430b94ba42SJung-uk Kim 9440b94ba42SJung-uk Kim /* Hard to analyze argument types, sow we won't */ 9450b94ba42SJung-uk Kim /* For now, just treat any arg as a typematch */ 9460b94ba42SJung-uk Kim 9470b94ba42SJung-uk Kim /* ThisNodeBtype = RequiredBtypes; */ 9480b94ba42SJung-uk Kim break; 9490b94ba42SJung-uk Kim 9500b94ba42SJung-uk Kim case PARSEOP_DEBUG: 9510b94ba42SJung-uk Kim break; 9520b94ba42SJung-uk Kim 9530b94ba42SJung-uk Kim case PARSEOP_REFOF: 9540b94ba42SJung-uk Kim case PARSEOP_INDEX: 9550b94ba42SJung-uk Kim default: 9560b94ba42SJung-uk Kim break; 9570b94ba42SJung-uk Kim 9580b94ba42SJung-uk Kim } 9590b94ba42SJung-uk Kim break; 9600b94ba42SJung-uk Kim 9610b94ba42SJung-uk Kim case ARGI_INTEGER: 9620b94ba42SJung-uk Kim default: 9630b94ba42SJung-uk Kim break; 9640b94ba42SJung-uk Kim } 9650b94ba42SJung-uk Kim 9660b94ba42SJung-uk Kim 9670b94ba42SJung-uk Kim CommonBtypes = ThisNodeBtype & RequiredBtypes; 9680b94ba42SJung-uk Kim 9690b94ba42SJung-uk Kim if (ArgOp->Asl.ParseOpcode == PARSEOP_METHODCALL) 9700b94ba42SJung-uk Kim { 9710b94ba42SJung-uk Kim if (AnIsInternalMethod (ArgOp)) 9720b94ba42SJung-uk Kim { 9730b94ba42SJung-uk Kim return (AE_OK); 9740b94ba42SJung-uk Kim } 9750b94ba42SJung-uk Kim 9760b94ba42SJung-uk Kim /* Check a method call for a valid return value */ 9770b94ba42SJung-uk Kim 9780b94ba42SJung-uk Kim AnCheckMethodReturnValue (Op, OpInfo, ArgOp, 9790b94ba42SJung-uk Kim RequiredBtypes, ThisNodeBtype); 9800b94ba42SJung-uk Kim } 9810b94ba42SJung-uk Kim 9820b94ba42SJung-uk Kim /* 9830b94ba42SJung-uk Kim * Now check if the actual type(s) match at least one 9840b94ba42SJung-uk Kim * bit to the required type 9850b94ba42SJung-uk Kim */ 9860b94ba42SJung-uk Kim else if (!CommonBtypes) 9870b94ba42SJung-uk Kim { 9880b94ba42SJung-uk Kim /* No match -- this is a type mismatch error */ 9890b94ba42SJung-uk Kim 9900b94ba42SJung-uk Kim AnFormatBtype (StringBuffer, ThisNodeBtype); 9910b94ba42SJung-uk Kim AnFormatBtype (StringBuffer2, RequiredBtypes); 9920b94ba42SJung-uk Kim 9930b94ba42SJung-uk Kim sprintf (MsgBuffer, "[%s] found, %s operator requires [%s]", 9940b94ba42SJung-uk Kim StringBuffer, OpInfo->Name, StringBuffer2); 9950b94ba42SJung-uk Kim 9960b94ba42SJung-uk Kim AslError (ASL_ERROR, ASL_MSG_INVALID_TYPE, ArgOp, MsgBuffer); 9970b94ba42SJung-uk Kim } 9980b94ba42SJung-uk Kim 9990b94ba42SJung-uk Kim NextArgument: 10000b94ba42SJung-uk Kim ArgOp = ArgOp->Asl.Next; 10010b94ba42SJung-uk Kim INCREMENT_ARG_LIST (RuntimeArgTypes2); 10020b94ba42SJung-uk Kim } 10030b94ba42SJung-uk Kim break; 10040b94ba42SJung-uk Kim 10050b94ba42SJung-uk Kim default: 10060b94ba42SJung-uk Kim break; 10070b94ba42SJung-uk Kim } 10080b94ba42SJung-uk Kim 10090b94ba42SJung-uk Kim return (AE_OK); 10100b94ba42SJung-uk Kim } 10110b94ba42SJung-uk Kim 10120b94ba42SJung-uk Kim 10130b94ba42SJung-uk Kim /******************************************************************************* 10140b94ba42SJung-uk Kim * 10150b94ba42SJung-uk Kim * FUNCTION: AnOtherSemanticAnalysisWalkBegin 10160b94ba42SJung-uk Kim * 10170b94ba42SJung-uk Kim * PARAMETERS: ASL_WALK_CALLBACK 10180b94ba42SJung-uk Kim * 10190b94ba42SJung-uk Kim * RETURN: Status 10200b94ba42SJung-uk Kim * 10210b94ba42SJung-uk Kim * DESCRIPTION: Descending callback for the analysis walk. Checks for 10220b94ba42SJung-uk Kim * miscellaneous issues in the code. 10230b94ba42SJung-uk Kim * 10240b94ba42SJung-uk Kim ******************************************************************************/ 10250b94ba42SJung-uk Kim 10260b94ba42SJung-uk Kim ACPI_STATUS 10270b94ba42SJung-uk Kim AnOtherSemanticAnalysisWalkBegin ( 10280b94ba42SJung-uk Kim ACPI_PARSE_OBJECT *Op, 10290b94ba42SJung-uk Kim UINT32 Level, 10300b94ba42SJung-uk Kim void *Context) 10310b94ba42SJung-uk Kim { 10320b94ba42SJung-uk Kim ACPI_PARSE_OBJECT *ArgNode; 10330b94ba42SJung-uk Kim ACPI_PARSE_OBJECT *PrevArgNode = NULL; 10340b94ba42SJung-uk Kim const ACPI_OPCODE_INFO *OpInfo; 10353f0275a0SJung-uk Kim ACPI_NAMESPACE_NODE *Node; 10360b94ba42SJung-uk Kim 10370b94ba42SJung-uk Kim 10380b94ba42SJung-uk Kim OpInfo = AcpiPsGetOpcodeInfo (Op->Asl.AmlOpcode); 10390b94ba42SJung-uk Kim 10400b94ba42SJung-uk Kim /* 10410b94ba42SJung-uk Kim * Determine if an execution class operator actually does something by 10420b94ba42SJung-uk Kim * checking if it has a target and/or the function return value is used. 10430b94ba42SJung-uk Kim * (Target is optional, so a standalone statement can actually do nothing.) 10440b94ba42SJung-uk Kim */ 10450b94ba42SJung-uk Kim if ((OpInfo->Class == AML_CLASS_EXECUTE) && 10460b94ba42SJung-uk Kim (OpInfo->Flags & AML_HAS_RETVAL) && 10470b94ba42SJung-uk Kim (!AnIsResultUsed (Op))) 10480b94ba42SJung-uk Kim { 10490b94ba42SJung-uk Kim if (OpInfo->Flags & AML_HAS_TARGET) 10500b94ba42SJung-uk Kim { 10510b94ba42SJung-uk Kim /* 10520b94ba42SJung-uk Kim * Find the target node, it is always the last child. If the traget 10530b94ba42SJung-uk Kim * is not specified in the ASL, a default node of type Zero was 10540b94ba42SJung-uk Kim * created by the parser. 10550b94ba42SJung-uk Kim */ 10560b94ba42SJung-uk Kim ArgNode = Op->Asl.Child; 10570b94ba42SJung-uk Kim while (ArgNode->Asl.Next) 10580b94ba42SJung-uk Kim { 10590b94ba42SJung-uk Kim PrevArgNode = ArgNode; 10600b94ba42SJung-uk Kim ArgNode = ArgNode->Asl.Next; 10610b94ba42SJung-uk Kim } 10620b94ba42SJung-uk Kim 10630b94ba42SJung-uk Kim /* Divide() is the only weird case, it has two targets */ 10640b94ba42SJung-uk Kim 10650b94ba42SJung-uk Kim if (Op->Asl.AmlOpcode == AML_DIVIDE_OP) 10660b94ba42SJung-uk Kim { 10670b94ba42SJung-uk Kim if ((ArgNode->Asl.ParseOpcode == PARSEOP_ZERO) && 10680b94ba42SJung-uk Kim (PrevArgNode) && 10690b94ba42SJung-uk Kim (PrevArgNode->Asl.ParseOpcode == PARSEOP_ZERO)) 10700b94ba42SJung-uk Kim { 10710b94ba42SJung-uk Kim AslError (ASL_WARNING, ASL_MSG_RESULT_NOT_USED, 10720b94ba42SJung-uk Kim Op, Op->Asl.ExternalName); 10730b94ba42SJung-uk Kim } 10740b94ba42SJung-uk Kim } 10750b94ba42SJung-uk Kim else if (ArgNode->Asl.ParseOpcode == PARSEOP_ZERO) 10760b94ba42SJung-uk Kim { 10770b94ba42SJung-uk Kim AslError (ASL_WARNING, ASL_MSG_RESULT_NOT_USED, 10780b94ba42SJung-uk Kim Op, Op->Asl.ExternalName); 10790b94ba42SJung-uk Kim } 10800b94ba42SJung-uk Kim } 10810b94ba42SJung-uk Kim else 10820b94ba42SJung-uk Kim { 10830b94ba42SJung-uk Kim /* 10840b94ba42SJung-uk Kim * Has no target and the result is not used. Only a couple opcodes 10850b94ba42SJung-uk Kim * can have this combination. 10860b94ba42SJung-uk Kim */ 10870b94ba42SJung-uk Kim switch (Op->Asl.ParseOpcode) 10880b94ba42SJung-uk Kim { 10890b94ba42SJung-uk Kim case PARSEOP_ACQUIRE: 10900b94ba42SJung-uk Kim case PARSEOP_WAIT: 10910b94ba42SJung-uk Kim case PARSEOP_LOADTABLE: 10920b94ba42SJung-uk Kim break; 10930b94ba42SJung-uk Kim 10940b94ba42SJung-uk Kim default: 10950b94ba42SJung-uk Kim AslError (ASL_WARNING, ASL_MSG_RESULT_NOT_USED, 10960b94ba42SJung-uk Kim Op, Op->Asl.ExternalName); 10970b94ba42SJung-uk Kim break; 10980b94ba42SJung-uk Kim } 10990b94ba42SJung-uk Kim } 11000b94ba42SJung-uk Kim } 11010b94ba42SJung-uk Kim 11020b94ba42SJung-uk Kim 11030b94ba42SJung-uk Kim /* 11040b94ba42SJung-uk Kim * Semantic checks for individual ASL operators 11050b94ba42SJung-uk Kim */ 11060b94ba42SJung-uk Kim switch (Op->Asl.ParseOpcode) 11070b94ba42SJung-uk Kim { 11080b94ba42SJung-uk Kim case PARSEOP_ACQUIRE: 11090b94ba42SJung-uk Kim case PARSEOP_WAIT: 11100b94ba42SJung-uk Kim /* 11110b94ba42SJung-uk Kim * Emit a warning if the timeout parameter for these operators is not 11120b94ba42SJung-uk Kim * ACPI_WAIT_FOREVER, and the result value from the operator is not 11130b94ba42SJung-uk Kim * checked, meaning that a timeout could happen, but the code 11140b94ba42SJung-uk Kim * would not know about it. 11150b94ba42SJung-uk Kim */ 11160b94ba42SJung-uk Kim 11170b94ba42SJung-uk Kim /* First child is the namepath, 2nd child is timeout */ 11180b94ba42SJung-uk Kim 11190b94ba42SJung-uk Kim ArgNode = Op->Asl.Child; 11200b94ba42SJung-uk Kim ArgNode = ArgNode->Asl.Next; 11210b94ba42SJung-uk Kim 11220b94ba42SJung-uk Kim /* 11230b94ba42SJung-uk Kim * Check for the WAIT_FOREVER case - defined by the ACPI spec to be 11240b94ba42SJung-uk Kim * 0xFFFF or greater 11250b94ba42SJung-uk Kim */ 11260b94ba42SJung-uk Kim if (((ArgNode->Asl.ParseOpcode == PARSEOP_WORDCONST) || 11270b94ba42SJung-uk Kim (ArgNode->Asl.ParseOpcode == PARSEOP_INTEGER)) && 11280b94ba42SJung-uk Kim (ArgNode->Asl.Value.Integer >= (UINT64) ACPI_WAIT_FOREVER)) 11290b94ba42SJung-uk Kim { 11300b94ba42SJung-uk Kim break; 11310b94ba42SJung-uk Kim } 11320b94ba42SJung-uk Kim 11330b94ba42SJung-uk Kim /* 11340b94ba42SJung-uk Kim * The operation could timeout. If the return value is not used 11350b94ba42SJung-uk Kim * (indicates timeout occurred), issue a warning 11360b94ba42SJung-uk Kim */ 11370b94ba42SJung-uk Kim if (!AnIsResultUsed (Op)) 11380b94ba42SJung-uk Kim { 11390b94ba42SJung-uk Kim AslError (ASL_WARNING, ASL_MSG_TIMEOUT, ArgNode, 11400b94ba42SJung-uk Kim Op->Asl.ExternalName); 11410b94ba42SJung-uk Kim } 11420b94ba42SJung-uk Kim break; 11430b94ba42SJung-uk Kim 11440b94ba42SJung-uk Kim case PARSEOP_CREATEFIELD: 11450b94ba42SJung-uk Kim /* 11460b94ba42SJung-uk Kim * Check for a zero Length (NumBits) operand. NumBits is the 3rd operand 11470b94ba42SJung-uk Kim */ 11480b94ba42SJung-uk Kim ArgNode = Op->Asl.Child; 11490b94ba42SJung-uk Kim ArgNode = ArgNode->Asl.Next; 11500b94ba42SJung-uk Kim ArgNode = ArgNode->Asl.Next; 11510b94ba42SJung-uk Kim 11520b94ba42SJung-uk Kim if ((ArgNode->Asl.ParseOpcode == PARSEOP_ZERO) || 11530b94ba42SJung-uk Kim ((ArgNode->Asl.ParseOpcode == PARSEOP_INTEGER) && 11540b94ba42SJung-uk Kim (ArgNode->Asl.Value.Integer == 0))) 11550b94ba42SJung-uk Kim { 11560b94ba42SJung-uk Kim AslError (ASL_ERROR, ASL_MSG_NON_ZERO, ArgNode, NULL); 11570b94ba42SJung-uk Kim } 11580b94ba42SJung-uk Kim break; 11590b94ba42SJung-uk Kim 11603f0275a0SJung-uk Kim case PARSEOP_CONNECTION: 11613f0275a0SJung-uk Kim /* 11623f0275a0SJung-uk Kim * Ensure that the referenced operation region has the correct SPACE_ID. 11633f0275a0SJung-uk Kim * From the grammar/parser, we know the parent is a FIELD definition. 11643f0275a0SJung-uk Kim */ 11653f0275a0SJung-uk Kim ArgNode = Op->Asl.Parent; /* Field definition */ 11663f0275a0SJung-uk Kim ArgNode = ArgNode->Asl.Child; /* First child is the OpRegion Name */ 11673f0275a0SJung-uk Kim Node = ArgNode->Asl.Node; /* OpRegion namespace node */ 11683f0275a0SJung-uk Kim 11693f0275a0SJung-uk Kim ArgNode = Node->Op; /* OpRegion definition */ 11703f0275a0SJung-uk Kim ArgNode = ArgNode->Asl.Child; /* First child is the OpRegion Name */ 11713f0275a0SJung-uk Kim ArgNode = ArgNode->Asl.Next; /* Next peer is the SPACE_ID (what we want) */ 11723f0275a0SJung-uk Kim 11733f0275a0SJung-uk Kim /* 11743f0275a0SJung-uk Kim * The Connection() operator is only valid for the following operation 11753f0275a0SJung-uk Kim * region SpaceIds: GeneralPurposeIo and GenericSerialBus. 11763f0275a0SJung-uk Kim */ 11773f0275a0SJung-uk Kim if ((ArgNode->Asl.Value.Integer != ACPI_ADR_SPACE_GPIO) && 11783f0275a0SJung-uk Kim (ArgNode->Asl.Value.Integer != ACPI_ADR_SPACE_GSBUS)) 11793f0275a0SJung-uk Kim { 11803f0275a0SJung-uk Kim AslError (ASL_ERROR, ASL_MSG_CONNECTION_INVALID, Op, NULL); 11813f0275a0SJung-uk Kim } 11823f0275a0SJung-uk Kim break; 11833f0275a0SJung-uk Kim 11843f0275a0SJung-uk Kim case PARSEOP_FIELD: 11853f0275a0SJung-uk Kim /* 11863f0275a0SJung-uk Kim * Ensure that fields for GeneralPurposeIo and GenericSerialBus 11873f0275a0SJung-uk Kim * contain at least one Connection() operator 11883f0275a0SJung-uk Kim */ 11893f0275a0SJung-uk Kim ArgNode = Op->Asl.Child; /* 1st child is the OpRegion Name */ 11903f0275a0SJung-uk Kim Node = ArgNode->Asl.Node; /* OpRegion namespace node */ 11913f0275a0SJung-uk Kim if (!Node) 11923f0275a0SJung-uk Kim { 11933f0275a0SJung-uk Kim break; 11943f0275a0SJung-uk Kim } 11953f0275a0SJung-uk Kim 11963f0275a0SJung-uk Kim ArgNode = Node->Op; /* OpRegion definition */ 11973f0275a0SJung-uk Kim ArgNode = ArgNode->Asl.Child; /* First child is the OpRegion Name */ 11983f0275a0SJung-uk Kim ArgNode = ArgNode->Asl.Next; /* Next peer is the SPACE_ID (what we want) */ 11993f0275a0SJung-uk Kim 12003f0275a0SJung-uk Kim /* We are only interested in GeneralPurposeIo and GenericSerialBus */ 12013f0275a0SJung-uk Kim 12023f0275a0SJung-uk Kim if ((ArgNode->Asl.Value.Integer != ACPI_ADR_SPACE_GPIO) && 12033f0275a0SJung-uk Kim (ArgNode->Asl.Value.Integer != ACPI_ADR_SPACE_GSBUS)) 12043f0275a0SJung-uk Kim { 12053f0275a0SJung-uk Kim break; 12063f0275a0SJung-uk Kim } 12073f0275a0SJung-uk Kim 12083f0275a0SJung-uk Kim ArgNode = Op->Asl.Child; /* 1st child is the OpRegion Name */ 12093f0275a0SJung-uk Kim ArgNode = ArgNode->Asl.Next; /* AccessType */ 12103f0275a0SJung-uk Kim ArgNode = ArgNode->Asl.Next; /* LockRule */ 12113f0275a0SJung-uk Kim ArgNode = ArgNode->Asl.Next; /* UpdateRule */ 12123f0275a0SJung-uk Kim ArgNode = ArgNode->Asl.Next; /* Start of FieldUnitList */ 12133f0275a0SJung-uk Kim 12143f0275a0SJung-uk Kim /* Walk the FieldUnitList */ 12153f0275a0SJung-uk Kim 12163f0275a0SJung-uk Kim while (ArgNode) 12173f0275a0SJung-uk Kim { 12183f0275a0SJung-uk Kim if (ArgNode->Asl.ParseOpcode == PARSEOP_CONNECTION) 12193f0275a0SJung-uk Kim { 12203f0275a0SJung-uk Kim break; 12213f0275a0SJung-uk Kim } 12223f0275a0SJung-uk Kim else if (ArgNode->Asl.ParseOpcode == PARSEOP_NAMESEG) 12233f0275a0SJung-uk Kim { 12243f0275a0SJung-uk Kim AslError (ASL_ERROR, ASL_MSG_CONNECTION_MISSING, ArgNode, NULL); 12253f0275a0SJung-uk Kim break; 12263f0275a0SJung-uk Kim } 12273f0275a0SJung-uk Kim 12283f0275a0SJung-uk Kim ArgNode = ArgNode->Asl.Next; 12293f0275a0SJung-uk Kim } 12303f0275a0SJung-uk Kim break; 12313f0275a0SJung-uk Kim 12320b94ba42SJung-uk Kim default: 12330b94ba42SJung-uk Kim break; 12340b94ba42SJung-uk Kim } 12350b94ba42SJung-uk Kim 12360b94ba42SJung-uk Kim return (AE_OK); 12370b94ba42SJung-uk Kim } 1238