1*385cc6b4SJerry Jelinek /****************************************************************************** 2*385cc6b4SJerry Jelinek * 3*385cc6b4SJerry Jelinek * Module Name: nsarguments - Validation of args for ACPI predefined methods 4*385cc6b4SJerry Jelinek * 5*385cc6b4SJerry Jelinek *****************************************************************************/ 6*385cc6b4SJerry Jelinek 7*385cc6b4SJerry Jelinek /* 8*385cc6b4SJerry Jelinek * Copyright (C) 2000 - 2016, Intel Corp. 9*385cc6b4SJerry Jelinek * All rights reserved. 10*385cc6b4SJerry Jelinek * 11*385cc6b4SJerry Jelinek * Redistribution and use in source and binary forms, with or without 12*385cc6b4SJerry Jelinek * modification, are permitted provided that the following conditions 13*385cc6b4SJerry Jelinek * are met: 14*385cc6b4SJerry Jelinek * 1. Redistributions of source code must retain the above copyright 15*385cc6b4SJerry Jelinek * notice, this list of conditions, and the following disclaimer, 16*385cc6b4SJerry Jelinek * without modification. 17*385cc6b4SJerry Jelinek * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18*385cc6b4SJerry Jelinek * substantially similar to the "NO WARRANTY" disclaimer below 19*385cc6b4SJerry Jelinek * ("Disclaimer") and any redistribution must be conditioned upon 20*385cc6b4SJerry Jelinek * including a substantially similar Disclaimer requirement for further 21*385cc6b4SJerry Jelinek * binary redistribution. 22*385cc6b4SJerry Jelinek * 3. Neither the names of the above-listed copyright holders nor the names 23*385cc6b4SJerry Jelinek * of any contributors may be used to endorse or promote products derived 24*385cc6b4SJerry Jelinek * from this software without specific prior written permission. 25*385cc6b4SJerry Jelinek * 26*385cc6b4SJerry Jelinek * Alternatively, this software may be distributed under the terms of the 27*385cc6b4SJerry Jelinek * GNU General Public License ("GPL") version 2 as published by the Free 28*385cc6b4SJerry Jelinek * Software Foundation. 29*385cc6b4SJerry Jelinek * 30*385cc6b4SJerry Jelinek * NO WARRANTY 31*385cc6b4SJerry Jelinek * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32*385cc6b4SJerry Jelinek * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33*385cc6b4SJerry Jelinek * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34*385cc6b4SJerry Jelinek * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35*385cc6b4SJerry Jelinek * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36*385cc6b4SJerry Jelinek * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37*385cc6b4SJerry Jelinek * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38*385cc6b4SJerry Jelinek * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39*385cc6b4SJerry Jelinek * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40*385cc6b4SJerry Jelinek * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41*385cc6b4SJerry Jelinek * POSSIBILITY OF SUCH DAMAGES. 42*385cc6b4SJerry Jelinek */ 43*385cc6b4SJerry Jelinek 44*385cc6b4SJerry Jelinek #include "acpi.h" 45*385cc6b4SJerry Jelinek #include "accommon.h" 46*385cc6b4SJerry Jelinek #include "acnamesp.h" 47*385cc6b4SJerry Jelinek #include "acpredef.h" 48*385cc6b4SJerry Jelinek 49*385cc6b4SJerry Jelinek 50*385cc6b4SJerry Jelinek #define _COMPONENT ACPI_NAMESPACE 51*385cc6b4SJerry Jelinek ACPI_MODULE_NAME ("nsarguments") 52*385cc6b4SJerry Jelinek 53*385cc6b4SJerry Jelinek 54*385cc6b4SJerry Jelinek /******************************************************************************* 55*385cc6b4SJerry Jelinek * 56*385cc6b4SJerry Jelinek * FUNCTION: AcpiNsCheckArgumentTypes 57*385cc6b4SJerry Jelinek * 58*385cc6b4SJerry Jelinek * PARAMETERS: Info - Method execution information block 59*385cc6b4SJerry Jelinek * 60*385cc6b4SJerry Jelinek * RETURN: None 61*385cc6b4SJerry Jelinek * 62*385cc6b4SJerry Jelinek * DESCRIPTION: Check the incoming argument count and all argument types 63*385cc6b4SJerry Jelinek * against the argument type list for a predefined name. 64*385cc6b4SJerry Jelinek * 65*385cc6b4SJerry Jelinek ******************************************************************************/ 66*385cc6b4SJerry Jelinek 67*385cc6b4SJerry Jelinek void 68*385cc6b4SJerry Jelinek AcpiNsCheckArgumentTypes ( 69*385cc6b4SJerry Jelinek ACPI_EVALUATE_INFO *Info) 70*385cc6b4SJerry Jelinek { 71*385cc6b4SJerry Jelinek UINT16 ArgTypeList; 72*385cc6b4SJerry Jelinek UINT8 ArgCount; 73*385cc6b4SJerry Jelinek UINT8 ArgType; 74*385cc6b4SJerry Jelinek UINT8 UserArgType; 75*385cc6b4SJerry Jelinek UINT32 i; 76*385cc6b4SJerry Jelinek 77*385cc6b4SJerry Jelinek 78*385cc6b4SJerry Jelinek /* If not a predefined name, cannot typecheck args */ 79*385cc6b4SJerry Jelinek 80*385cc6b4SJerry Jelinek if (!Info->Predefined) 81*385cc6b4SJerry Jelinek { 82*385cc6b4SJerry Jelinek return; 83*385cc6b4SJerry Jelinek } 84*385cc6b4SJerry Jelinek 85*385cc6b4SJerry Jelinek ArgTypeList = Info->Predefined->Info.ArgumentList; 86*385cc6b4SJerry Jelinek ArgCount = METHOD_GET_ARG_COUNT (ArgTypeList); 87*385cc6b4SJerry Jelinek 88*385cc6b4SJerry Jelinek /* Typecheck all arguments */ 89*385cc6b4SJerry Jelinek 90*385cc6b4SJerry Jelinek for (i = 0; ((i < ArgCount) && (i < Info->ParamCount)); i++) 91*385cc6b4SJerry Jelinek { 92*385cc6b4SJerry Jelinek ArgType = METHOD_GET_NEXT_TYPE (ArgTypeList); 93*385cc6b4SJerry Jelinek UserArgType = Info->Parameters[i]->Common.Type; 94*385cc6b4SJerry Jelinek 95*385cc6b4SJerry Jelinek if (UserArgType != ArgType) 96*385cc6b4SJerry Jelinek { 97*385cc6b4SJerry Jelinek ACPI_WARN_PREDEFINED ((AE_INFO, Info->FullPathname, ACPI_WARN_ALWAYS, 98*385cc6b4SJerry Jelinek "Argument #%u type mismatch - " 99*385cc6b4SJerry Jelinek "Found [%s], ACPI requires [%s]", (i + 1), 100*385cc6b4SJerry Jelinek AcpiUtGetTypeName (UserArgType), 101*385cc6b4SJerry Jelinek AcpiUtGetTypeName (ArgType))); 102*385cc6b4SJerry Jelinek } 103*385cc6b4SJerry Jelinek } 104*385cc6b4SJerry Jelinek } 105*385cc6b4SJerry Jelinek 106*385cc6b4SJerry Jelinek 107*385cc6b4SJerry Jelinek /******************************************************************************* 108*385cc6b4SJerry Jelinek * 109*385cc6b4SJerry Jelinek * FUNCTION: AcpiNsCheckAcpiCompliance 110*385cc6b4SJerry Jelinek * 111*385cc6b4SJerry Jelinek * PARAMETERS: Pathname - Full pathname to the node (for error msgs) 112*385cc6b4SJerry Jelinek * Node - Namespace node for the method/object 113*385cc6b4SJerry Jelinek * Predefined - Pointer to entry in predefined name table 114*385cc6b4SJerry Jelinek * 115*385cc6b4SJerry Jelinek * RETURN: None 116*385cc6b4SJerry Jelinek * 117*385cc6b4SJerry Jelinek * DESCRIPTION: Check that the declared parameter count (in ASL/AML) for a 118*385cc6b4SJerry Jelinek * predefined name is what is expected (matches what is defined in 119*385cc6b4SJerry Jelinek * the ACPI specification for this predefined name.) 120*385cc6b4SJerry Jelinek * 121*385cc6b4SJerry Jelinek ******************************************************************************/ 122*385cc6b4SJerry Jelinek 123*385cc6b4SJerry Jelinek void 124*385cc6b4SJerry Jelinek AcpiNsCheckAcpiCompliance ( 125*385cc6b4SJerry Jelinek char *Pathname, 126*385cc6b4SJerry Jelinek ACPI_NAMESPACE_NODE *Node, 127*385cc6b4SJerry Jelinek const ACPI_PREDEFINED_INFO *Predefined) 128*385cc6b4SJerry Jelinek { 129*385cc6b4SJerry Jelinek UINT32 AmlParamCount; 130*385cc6b4SJerry Jelinek UINT32 RequiredParamCount; 131*385cc6b4SJerry Jelinek 132*385cc6b4SJerry Jelinek 133*385cc6b4SJerry Jelinek if (!Predefined) 134*385cc6b4SJerry Jelinek { 135*385cc6b4SJerry Jelinek return; 136*385cc6b4SJerry Jelinek } 137*385cc6b4SJerry Jelinek 138*385cc6b4SJerry Jelinek /* Get the ACPI-required arg count from the predefined info table */ 139*385cc6b4SJerry Jelinek 140*385cc6b4SJerry Jelinek RequiredParamCount = 141*385cc6b4SJerry Jelinek METHOD_GET_ARG_COUNT (Predefined->Info.ArgumentList); 142*385cc6b4SJerry Jelinek 143*385cc6b4SJerry Jelinek /* 144*385cc6b4SJerry Jelinek * If this object is not a control method, we can check if the ACPI 145*385cc6b4SJerry Jelinek * spec requires that it be a method. 146*385cc6b4SJerry Jelinek */ 147*385cc6b4SJerry Jelinek if (Node->Type != ACPI_TYPE_METHOD) 148*385cc6b4SJerry Jelinek { 149*385cc6b4SJerry Jelinek if (RequiredParamCount > 0) 150*385cc6b4SJerry Jelinek { 151*385cc6b4SJerry Jelinek /* Object requires args, must be implemented as a method */ 152*385cc6b4SJerry Jelinek 153*385cc6b4SJerry Jelinek ACPI_BIOS_ERROR_PREDEFINED ((AE_INFO, Pathname, ACPI_WARN_ALWAYS, 154*385cc6b4SJerry Jelinek "Object (%s) must be a control method with %u arguments", 155*385cc6b4SJerry Jelinek AcpiUtGetTypeName (Node->Type), RequiredParamCount)); 156*385cc6b4SJerry Jelinek } 157*385cc6b4SJerry Jelinek else if (!RequiredParamCount && !Predefined->Info.ExpectedBtypes) 158*385cc6b4SJerry Jelinek { 159*385cc6b4SJerry Jelinek /* Object requires no args and no return value, must be a method */ 160*385cc6b4SJerry Jelinek 161*385cc6b4SJerry Jelinek ACPI_BIOS_ERROR_PREDEFINED ((AE_INFO, Pathname, ACPI_WARN_ALWAYS, 162*385cc6b4SJerry Jelinek "Object (%s) must be a control method " 163*385cc6b4SJerry Jelinek "with no arguments and no return value", 164*385cc6b4SJerry Jelinek AcpiUtGetTypeName (Node->Type))); 165*385cc6b4SJerry Jelinek } 166*385cc6b4SJerry Jelinek 167*385cc6b4SJerry Jelinek return; 168*385cc6b4SJerry Jelinek } 169*385cc6b4SJerry Jelinek 170*385cc6b4SJerry Jelinek /* 171*385cc6b4SJerry Jelinek * This is a control method. 172*385cc6b4SJerry Jelinek * Check that the ASL/AML-defined parameter count for this method 173*385cc6b4SJerry Jelinek * matches the ACPI-required parameter count 174*385cc6b4SJerry Jelinek * 175*385cc6b4SJerry Jelinek * Some methods are allowed to have a "minimum" number of args (_SCP) 176*385cc6b4SJerry Jelinek * because their definition in ACPI has changed over time. 177*385cc6b4SJerry Jelinek * 178*385cc6b4SJerry Jelinek * Note: These are BIOS errors in the declaration of the object 179*385cc6b4SJerry Jelinek */ 180*385cc6b4SJerry Jelinek AmlParamCount = Node->Object->Method.ParamCount; 181*385cc6b4SJerry Jelinek 182*385cc6b4SJerry Jelinek if (AmlParamCount < RequiredParamCount) 183*385cc6b4SJerry Jelinek { 184*385cc6b4SJerry Jelinek ACPI_BIOS_ERROR_PREDEFINED ((AE_INFO, Pathname, ACPI_WARN_ALWAYS, 185*385cc6b4SJerry Jelinek "Insufficient arguments - " 186*385cc6b4SJerry Jelinek "ASL declared %u, ACPI requires %u", 187*385cc6b4SJerry Jelinek AmlParamCount, RequiredParamCount)); 188*385cc6b4SJerry Jelinek } 189*385cc6b4SJerry Jelinek else if ((AmlParamCount > RequiredParamCount) && 190*385cc6b4SJerry Jelinek !(Predefined->Info.ArgumentList & ARG_COUNT_IS_MINIMUM)) 191*385cc6b4SJerry Jelinek { 192*385cc6b4SJerry Jelinek ACPI_BIOS_ERROR_PREDEFINED ((AE_INFO, Pathname, ACPI_WARN_ALWAYS, 193*385cc6b4SJerry Jelinek "Excess arguments - " 194*385cc6b4SJerry Jelinek "ASL declared %u, ACPI requires %u", 195*385cc6b4SJerry Jelinek AmlParamCount, RequiredParamCount)); 196*385cc6b4SJerry Jelinek } 197*385cc6b4SJerry Jelinek } 198*385cc6b4SJerry Jelinek 199*385cc6b4SJerry Jelinek 200*385cc6b4SJerry Jelinek /******************************************************************************* 201*385cc6b4SJerry Jelinek * 202*385cc6b4SJerry Jelinek * FUNCTION: AcpiNsCheckArgumentCount 203*385cc6b4SJerry Jelinek * 204*385cc6b4SJerry Jelinek * PARAMETERS: Pathname - Full pathname to the node (for error msgs) 205*385cc6b4SJerry Jelinek * Node - Namespace node for the method/object 206*385cc6b4SJerry Jelinek * UserParamCount - Number of args passed in by the caller 207*385cc6b4SJerry Jelinek * Predefined - Pointer to entry in predefined name table 208*385cc6b4SJerry Jelinek * 209*385cc6b4SJerry Jelinek * RETURN: None 210*385cc6b4SJerry Jelinek * 211*385cc6b4SJerry Jelinek * DESCRIPTION: Check that incoming argument count matches the declared 212*385cc6b4SJerry Jelinek * parameter count (in the ASL/AML) for an object. 213*385cc6b4SJerry Jelinek * 214*385cc6b4SJerry Jelinek ******************************************************************************/ 215*385cc6b4SJerry Jelinek 216*385cc6b4SJerry Jelinek void 217*385cc6b4SJerry Jelinek AcpiNsCheckArgumentCount ( 218*385cc6b4SJerry Jelinek char *Pathname, 219*385cc6b4SJerry Jelinek ACPI_NAMESPACE_NODE *Node, 220*385cc6b4SJerry Jelinek UINT32 UserParamCount, 221*385cc6b4SJerry Jelinek const ACPI_PREDEFINED_INFO *Predefined) 222*385cc6b4SJerry Jelinek { 223*385cc6b4SJerry Jelinek UINT32 AmlParamCount; 224*385cc6b4SJerry Jelinek UINT32 RequiredParamCount; 225*385cc6b4SJerry Jelinek 226*385cc6b4SJerry Jelinek 227*385cc6b4SJerry Jelinek if (!Predefined) 228*385cc6b4SJerry Jelinek { 229*385cc6b4SJerry Jelinek /* 230*385cc6b4SJerry Jelinek * Not a predefined name. Check the incoming user argument count 231*385cc6b4SJerry Jelinek * against the count that is specified in the method/object. 232*385cc6b4SJerry Jelinek */ 233*385cc6b4SJerry Jelinek if (Node->Type != ACPI_TYPE_METHOD) 234*385cc6b4SJerry Jelinek { 235*385cc6b4SJerry Jelinek if (UserParamCount) 236*385cc6b4SJerry Jelinek { 237*385cc6b4SJerry Jelinek ACPI_INFO_PREDEFINED ((AE_INFO, Pathname, ACPI_WARN_ALWAYS, 238*385cc6b4SJerry Jelinek "%u arguments were passed to a non-method ACPI object (%s)", 239*385cc6b4SJerry Jelinek UserParamCount, AcpiUtGetTypeName (Node->Type))); 240*385cc6b4SJerry Jelinek } 241*385cc6b4SJerry Jelinek 242*385cc6b4SJerry Jelinek return; 243*385cc6b4SJerry Jelinek } 244*385cc6b4SJerry Jelinek 245*385cc6b4SJerry Jelinek /* 246*385cc6b4SJerry Jelinek * This is a control method. Check the parameter count. 247*385cc6b4SJerry Jelinek * We can only check the incoming argument count against the 248*385cc6b4SJerry Jelinek * argument count declared for the method in the ASL/AML. 249*385cc6b4SJerry Jelinek * 250*385cc6b4SJerry Jelinek * Emit a message if too few or too many arguments have been passed 251*385cc6b4SJerry Jelinek * by the caller. 252*385cc6b4SJerry Jelinek * 253*385cc6b4SJerry Jelinek * Note: Too many arguments will not cause the method to 254*385cc6b4SJerry Jelinek * fail. However, the method will fail if there are too few 255*385cc6b4SJerry Jelinek * arguments and the method attempts to use one of the missing ones. 256*385cc6b4SJerry Jelinek */ 257*385cc6b4SJerry Jelinek AmlParamCount = Node->Object->Method.ParamCount; 258*385cc6b4SJerry Jelinek 259*385cc6b4SJerry Jelinek if (UserParamCount < AmlParamCount) 260*385cc6b4SJerry Jelinek { 261*385cc6b4SJerry Jelinek ACPI_WARN_PREDEFINED ((AE_INFO, Pathname, ACPI_WARN_ALWAYS, 262*385cc6b4SJerry Jelinek "Insufficient arguments - " 263*385cc6b4SJerry Jelinek "Caller passed %u, method requires %u", 264*385cc6b4SJerry Jelinek UserParamCount, AmlParamCount)); 265*385cc6b4SJerry Jelinek } 266*385cc6b4SJerry Jelinek else if (UserParamCount > AmlParamCount) 267*385cc6b4SJerry Jelinek { 268*385cc6b4SJerry Jelinek ACPI_INFO_PREDEFINED ((AE_INFO, Pathname, ACPI_WARN_ALWAYS, 269*385cc6b4SJerry Jelinek "Excess arguments - " 270*385cc6b4SJerry Jelinek "Caller passed %u, method requires %u", 271*385cc6b4SJerry Jelinek UserParamCount, AmlParamCount)); 272*385cc6b4SJerry Jelinek } 273*385cc6b4SJerry Jelinek 274*385cc6b4SJerry Jelinek return; 275*385cc6b4SJerry Jelinek } 276*385cc6b4SJerry Jelinek 277*385cc6b4SJerry Jelinek /* 278*385cc6b4SJerry Jelinek * This is a predefined name. Validate the user-supplied parameter 279*385cc6b4SJerry Jelinek * count against the ACPI specification. We don't validate against 280*385cc6b4SJerry Jelinek * the method itself because what is important here is that the 281*385cc6b4SJerry Jelinek * caller is in conformance with the spec. (The arg count for the 282*385cc6b4SJerry Jelinek * method was checked against the ACPI spec earlier.) 283*385cc6b4SJerry Jelinek * 284*385cc6b4SJerry Jelinek * Some methods are allowed to have a "minimum" number of args (_SCP) 285*385cc6b4SJerry Jelinek * because their definition in ACPI has changed over time. 286*385cc6b4SJerry Jelinek */ 287*385cc6b4SJerry Jelinek RequiredParamCount = 288*385cc6b4SJerry Jelinek METHOD_GET_ARG_COUNT (Predefined->Info.ArgumentList); 289*385cc6b4SJerry Jelinek 290*385cc6b4SJerry Jelinek if (UserParamCount < RequiredParamCount) 291*385cc6b4SJerry Jelinek { 292*385cc6b4SJerry Jelinek ACPI_WARN_PREDEFINED ((AE_INFO, Pathname, ACPI_WARN_ALWAYS, 293*385cc6b4SJerry Jelinek "Insufficient arguments - " 294*385cc6b4SJerry Jelinek "Caller passed %u, ACPI requires %u", 295*385cc6b4SJerry Jelinek UserParamCount, RequiredParamCount)); 296*385cc6b4SJerry Jelinek } 297*385cc6b4SJerry Jelinek else if ((UserParamCount > RequiredParamCount) && 298*385cc6b4SJerry Jelinek !(Predefined->Info.ArgumentList & ARG_COUNT_IS_MINIMUM)) 299*385cc6b4SJerry Jelinek { 300*385cc6b4SJerry Jelinek ACPI_INFO_PREDEFINED ((AE_INFO, Pathname, ACPI_WARN_ALWAYS, 301*385cc6b4SJerry Jelinek "Excess arguments - " 302*385cc6b4SJerry Jelinek "Caller passed %u, ACPI requires %u", 303*385cc6b4SJerry Jelinek UserParamCount, RequiredParamCount)); 304*385cc6b4SJerry Jelinek } 305*385cc6b4SJerry Jelinek } 306