1249637Sjkim/****************************************************************************** 2249637Sjkim * 3249637Sjkim * Module Name: nsarguments - Validation of args for ACPI predefined methods 4249637Sjkim * 5249637Sjkim *****************************************************************************/ 6249637Sjkim 7249637Sjkim/* 8306536Sjkim * Copyright (C) 2000 - 2016, Intel Corp. 9249637Sjkim * All rights reserved. 10249637Sjkim * 11249637Sjkim * Redistribution and use in source and binary forms, with or without 12249637Sjkim * modification, are permitted provided that the following conditions 13249637Sjkim * are met: 14249637Sjkim * 1. Redistributions of source code must retain the above copyright 15249637Sjkim * notice, this list of conditions, and the following disclaimer, 16249637Sjkim * without modification. 17249637Sjkim * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18249637Sjkim * substantially similar to the "NO WARRANTY" disclaimer below 19249637Sjkim * ("Disclaimer") and any redistribution must be conditioned upon 20249637Sjkim * including a substantially similar Disclaimer requirement for further 21249637Sjkim * binary redistribution. 22249637Sjkim * 3. Neither the names of the above-listed copyright holders nor the names 23249637Sjkim * of any contributors may be used to endorse or promote products derived 24249637Sjkim * from this software without specific prior written permission. 25249637Sjkim * 26249637Sjkim * Alternatively, this software may be distributed under the terms of the 27249637Sjkim * GNU General Public License ("GPL") version 2 as published by the Free 28249637Sjkim * Software Foundation. 29249637Sjkim * 30249637Sjkim * NO WARRANTY 31249637Sjkim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32249637Sjkim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33249637Sjkim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34249637Sjkim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35249637Sjkim * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36249637Sjkim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37249637Sjkim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38249637Sjkim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39249637Sjkim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40249637Sjkim * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41249637Sjkim * POSSIBILITY OF SUCH DAMAGES. 42249637Sjkim */ 43249637Sjkim 44249663Sjkim#include <contrib/dev/acpica/include/acpi.h> 45249663Sjkim#include <contrib/dev/acpica/include/accommon.h> 46249663Sjkim#include <contrib/dev/acpica/include/acnamesp.h> 47249663Sjkim#include <contrib/dev/acpica/include/acpredef.h> 48249637Sjkim 49249637Sjkim 50249637Sjkim#define _COMPONENT ACPI_NAMESPACE 51249637Sjkim ACPI_MODULE_NAME ("nsarguments") 52249637Sjkim 53249637Sjkim 54249637Sjkim/******************************************************************************* 55249637Sjkim * 56249637Sjkim * FUNCTION: AcpiNsCheckArgumentTypes 57249637Sjkim * 58249637Sjkim * PARAMETERS: Info - Method execution information block 59249637Sjkim * 60249637Sjkim * RETURN: None 61249637Sjkim * 62249637Sjkim * DESCRIPTION: Check the incoming argument count and all argument types 63249637Sjkim * against the argument type list for a predefined name. 64249637Sjkim * 65249637Sjkim ******************************************************************************/ 66249637Sjkim 67249637Sjkimvoid 68249637SjkimAcpiNsCheckArgumentTypes ( 69249637Sjkim ACPI_EVALUATE_INFO *Info) 70249637Sjkim{ 71249637Sjkim UINT16 ArgTypeList; 72249637Sjkim UINT8 ArgCount; 73249637Sjkim UINT8 ArgType; 74249637Sjkim UINT8 UserArgType; 75249637Sjkim UINT32 i; 76249637Sjkim 77249637Sjkim 78249637Sjkim /* If not a predefined name, cannot typecheck args */ 79249637Sjkim 80249637Sjkim if (!Info->Predefined) 81249637Sjkim { 82249637Sjkim return; 83249637Sjkim } 84249637Sjkim 85249637Sjkim ArgTypeList = Info->Predefined->Info.ArgumentList; 86249637Sjkim ArgCount = METHOD_GET_ARG_COUNT (ArgTypeList); 87249637Sjkim 88249637Sjkim /* Typecheck all arguments */ 89249637Sjkim 90249637Sjkim for (i = 0; ((i < ArgCount) && (i < Info->ParamCount)); i++) 91249637Sjkim { 92249637Sjkim ArgType = METHOD_GET_NEXT_TYPE (ArgTypeList); 93249637Sjkim UserArgType = Info->Parameters[i]->Common.Type; 94249637Sjkim 95249637Sjkim if (UserArgType != ArgType) 96249637Sjkim { 97249637Sjkim ACPI_WARN_PREDEFINED ((AE_INFO, Info->FullPathname, ACPI_WARN_ALWAYS, 98249637Sjkim "Argument #%u type mismatch - " 99249637Sjkim "Found [%s], ACPI requires [%s]", (i + 1), 100249637Sjkim AcpiUtGetTypeName (UserArgType), 101249637Sjkim AcpiUtGetTypeName (ArgType))); 102249637Sjkim } 103249637Sjkim } 104249637Sjkim} 105249637Sjkim 106249637Sjkim 107249637Sjkim/******************************************************************************* 108249637Sjkim * 109249637Sjkim * FUNCTION: AcpiNsCheckAcpiCompliance 110249637Sjkim * 111249637Sjkim * PARAMETERS: Pathname - Full pathname to the node (for error msgs) 112249637Sjkim * Node - Namespace node for the method/object 113249637Sjkim * Predefined - Pointer to entry in predefined name table 114249637Sjkim * 115249637Sjkim * RETURN: None 116249637Sjkim * 117249637Sjkim * DESCRIPTION: Check that the declared parameter count (in ASL/AML) for a 118249637Sjkim * predefined name is what is expected (matches what is defined in 119249637Sjkim * the ACPI specification for this predefined name.) 120249637Sjkim * 121249637Sjkim ******************************************************************************/ 122249637Sjkim 123249637Sjkimvoid 124249637SjkimAcpiNsCheckAcpiCompliance ( 125249637Sjkim char *Pathname, 126249637Sjkim ACPI_NAMESPACE_NODE *Node, 127249637Sjkim const ACPI_PREDEFINED_INFO *Predefined) 128249637Sjkim{ 129249637Sjkim UINT32 AmlParamCount; 130249637Sjkim UINT32 RequiredParamCount; 131249637Sjkim 132249637Sjkim 133249637Sjkim if (!Predefined) 134249637Sjkim { 135249637Sjkim return; 136249637Sjkim } 137249637Sjkim 138249637Sjkim /* Get the ACPI-required arg count from the predefined info table */ 139249637Sjkim 140306536Sjkim RequiredParamCount = 141306536Sjkim METHOD_GET_ARG_COUNT (Predefined->Info.ArgumentList); 142249637Sjkim 143249637Sjkim /* 144249637Sjkim * If this object is not a control method, we can check if the ACPI 145249637Sjkim * spec requires that it be a method. 146249637Sjkim */ 147249637Sjkim if (Node->Type != ACPI_TYPE_METHOD) 148249637Sjkim { 149249637Sjkim if (RequiredParamCount > 0) 150249637Sjkim { 151249637Sjkim /* Object requires args, must be implemented as a method */ 152249637Sjkim 153249637Sjkim ACPI_BIOS_ERROR_PREDEFINED ((AE_INFO, Pathname, ACPI_WARN_ALWAYS, 154249637Sjkim "Object (%s) must be a control method with %u arguments", 155249637Sjkim AcpiUtGetTypeName (Node->Type), RequiredParamCount)); 156249637Sjkim } 157249637Sjkim else if (!RequiredParamCount && !Predefined->Info.ExpectedBtypes) 158249637Sjkim { 159249637Sjkim /* Object requires no args and no return value, must be a method */ 160249637Sjkim 161249637Sjkim ACPI_BIOS_ERROR_PREDEFINED ((AE_INFO, Pathname, ACPI_WARN_ALWAYS, 162249637Sjkim "Object (%s) must be a control method " 163249637Sjkim "with no arguments and no return value", 164249637Sjkim AcpiUtGetTypeName (Node->Type))); 165249637Sjkim } 166249637Sjkim 167249637Sjkim return; 168249637Sjkim } 169249637Sjkim 170249637Sjkim /* 171249637Sjkim * This is a control method. 172249637Sjkim * Check that the ASL/AML-defined parameter count for this method 173249637Sjkim * matches the ACPI-required parameter count 174249637Sjkim * 175249637Sjkim * Some methods are allowed to have a "minimum" number of args (_SCP) 176249637Sjkim * because their definition in ACPI has changed over time. 177249637Sjkim * 178249637Sjkim * Note: These are BIOS errors in the declaration of the object 179249637Sjkim */ 180249637Sjkim AmlParamCount = Node->Object->Method.ParamCount; 181249637Sjkim 182249637Sjkim if (AmlParamCount < RequiredParamCount) 183249637Sjkim { 184249637Sjkim ACPI_BIOS_ERROR_PREDEFINED ((AE_INFO, Pathname, ACPI_WARN_ALWAYS, 185249637Sjkim "Insufficient arguments - " 186249637Sjkim "ASL declared %u, ACPI requires %u", 187249637Sjkim AmlParamCount, RequiredParamCount)); 188249637Sjkim } 189249637Sjkim else if ((AmlParamCount > RequiredParamCount) && 190249637Sjkim !(Predefined->Info.ArgumentList & ARG_COUNT_IS_MINIMUM)) 191249637Sjkim { 192249637Sjkim ACPI_BIOS_ERROR_PREDEFINED ((AE_INFO, Pathname, ACPI_WARN_ALWAYS, 193249637Sjkim "Excess arguments - " 194249637Sjkim "ASL declared %u, ACPI requires %u", 195249637Sjkim AmlParamCount, RequiredParamCount)); 196249637Sjkim } 197249637Sjkim} 198249637Sjkim 199249637Sjkim 200249637Sjkim/******************************************************************************* 201249637Sjkim * 202249637Sjkim * FUNCTION: AcpiNsCheckArgumentCount 203249637Sjkim * 204249637Sjkim * PARAMETERS: Pathname - Full pathname to the node (for error msgs) 205249637Sjkim * Node - Namespace node for the method/object 206249637Sjkim * UserParamCount - Number of args passed in by the caller 207249637Sjkim * Predefined - Pointer to entry in predefined name table 208249637Sjkim * 209249637Sjkim * RETURN: None 210249637Sjkim * 211249637Sjkim * DESCRIPTION: Check that incoming argument count matches the declared 212249637Sjkim * parameter count (in the ASL/AML) for an object. 213249637Sjkim * 214249637Sjkim ******************************************************************************/ 215249637Sjkim 216249637Sjkimvoid 217249637SjkimAcpiNsCheckArgumentCount ( 218249637Sjkim char *Pathname, 219249637Sjkim ACPI_NAMESPACE_NODE *Node, 220249637Sjkim UINT32 UserParamCount, 221249637Sjkim const ACPI_PREDEFINED_INFO *Predefined) 222249637Sjkim{ 223249637Sjkim UINT32 AmlParamCount; 224249637Sjkim UINT32 RequiredParamCount; 225249637Sjkim 226249637Sjkim 227249637Sjkim if (!Predefined) 228249637Sjkim { 229249637Sjkim /* 230249637Sjkim * Not a predefined name. Check the incoming user argument count 231249637Sjkim * against the count that is specified in the method/object. 232249637Sjkim */ 233249637Sjkim if (Node->Type != ACPI_TYPE_METHOD) 234249637Sjkim { 235249637Sjkim if (UserParamCount) 236249637Sjkim { 237249637Sjkim ACPI_INFO_PREDEFINED ((AE_INFO, Pathname, ACPI_WARN_ALWAYS, 238249637Sjkim "%u arguments were passed to a non-method ACPI object (%s)", 239249637Sjkim UserParamCount, AcpiUtGetTypeName (Node->Type))); 240249637Sjkim } 241249637Sjkim 242249637Sjkim return; 243249637Sjkim } 244249637Sjkim 245249637Sjkim /* 246249637Sjkim * This is a control method. Check the parameter count. 247249637Sjkim * We can only check the incoming argument count against the 248249637Sjkim * argument count declared for the method in the ASL/AML. 249249637Sjkim * 250249637Sjkim * Emit a message if too few or too many arguments have been passed 251249637Sjkim * by the caller. 252249637Sjkim * 253249637Sjkim * Note: Too many arguments will not cause the method to 254249637Sjkim * fail. However, the method will fail if there are too few 255249637Sjkim * arguments and the method attempts to use one of the missing ones. 256249637Sjkim */ 257249637Sjkim AmlParamCount = Node->Object->Method.ParamCount; 258249637Sjkim 259249637Sjkim if (UserParamCount < AmlParamCount) 260249637Sjkim { 261249637Sjkim ACPI_WARN_PREDEFINED ((AE_INFO, Pathname, ACPI_WARN_ALWAYS, 262249637Sjkim "Insufficient arguments - " 263249637Sjkim "Caller passed %u, method requires %u", 264249637Sjkim UserParamCount, AmlParamCount)); 265249637Sjkim } 266249637Sjkim else if (UserParamCount > AmlParamCount) 267249637Sjkim { 268249637Sjkim ACPI_INFO_PREDEFINED ((AE_INFO, Pathname, ACPI_WARN_ALWAYS, 269249637Sjkim "Excess arguments - " 270249637Sjkim "Caller passed %u, method requires %u", 271249637Sjkim UserParamCount, AmlParamCount)); 272249637Sjkim } 273249637Sjkim 274249637Sjkim return; 275249637Sjkim } 276249637Sjkim 277249637Sjkim /* 278249637Sjkim * This is a predefined name. Validate the user-supplied parameter 279249637Sjkim * count against the ACPI specification. We don't validate against 280249637Sjkim * the method itself because what is important here is that the 281249637Sjkim * caller is in conformance with the spec. (The arg count for the 282249637Sjkim * method was checked against the ACPI spec earlier.) 283249637Sjkim * 284249637Sjkim * Some methods are allowed to have a "minimum" number of args (_SCP) 285249637Sjkim * because their definition in ACPI has changed over time. 286249637Sjkim */ 287306536Sjkim RequiredParamCount = 288306536Sjkim METHOD_GET_ARG_COUNT (Predefined->Info.ArgumentList); 289249637Sjkim 290249637Sjkim if (UserParamCount < RequiredParamCount) 291249637Sjkim { 292249637Sjkim ACPI_WARN_PREDEFINED ((AE_INFO, Pathname, ACPI_WARN_ALWAYS, 293249637Sjkim "Insufficient arguments - " 294249637Sjkim "Caller passed %u, ACPI requires %u", 295249637Sjkim UserParamCount, RequiredParamCount)); 296249637Sjkim } 297249637Sjkim else if ((UserParamCount > RequiredParamCount) && 298249637Sjkim !(Predefined->Info.ArgumentList & ARG_COUNT_IS_MINIMUM)) 299249637Sjkim { 300249637Sjkim ACPI_INFO_PREDEFINED ((AE_INFO, Pathname, ACPI_WARN_ALWAYS, 301249637Sjkim "Excess arguments - " 302249637Sjkim "Caller passed %u, ACPI requires %u", 303249637Sjkim UserParamCount, RequiredParamCount)); 304249637Sjkim } 305249637Sjkim} 306