1 /******************************************************************************* 2 * 3 * Module Name: nseval - Object evaluation, includes control method execution 4 * 5 ******************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2022, Intel Corp. 9 * All rights reserved. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions, and the following disclaimer, 16 * without modification. 17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18 * substantially similar to the "NO WARRANTY" disclaimer below 19 * ("Disclaimer") and any redistribution must be conditioned upon 20 * including a substantially similar Disclaimer requirement for further 21 * binary redistribution. 22 * 3. Neither the names of the above-listed copyright holders nor the names 23 * of any contributors may be used to endorse or promote products derived 24 * from this software without specific prior written permission. 25 * 26 * Alternatively, this software may be distributed under the terms of the 27 * GNU General Public License ("GPL") version 2 as published by the Free 28 * Software Foundation. 29 * 30 * NO WARRANTY 31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41 * POSSIBILITY OF SUCH DAMAGES. 42 */ 43 44 #include "acpi.h" 45 #include "accommon.h" 46 #include "acparser.h" 47 #include "acinterp.h" 48 #include "acnamesp.h" 49 50 51 #define _COMPONENT ACPI_NAMESPACE 52 ACPI_MODULE_NAME ("nseval") 53 54 55 /******************************************************************************* 56 * 57 * FUNCTION: AcpiNsEvaluate 58 * 59 * PARAMETERS: Info - Evaluation info block, contains these fields 60 * and more: 61 * PrefixNode - Prefix or Method/Object Node to execute 62 * RelativePath - Name of method to execute, If NULL, the 63 * Node is the object to execute 64 * Parameters - List of parameters to pass to the method, 65 * terminated by NULL. Params itself may be 66 * NULL if no parameters are being passed. 67 * ParameterType - Type of Parameter list 68 * ReturnObject - Where to put method's return value (if 69 * any). If NULL, no value is returned. 70 * Flags - ACPI_IGNORE_RETURN_VALUE to delete return 71 * 72 * RETURN: Status 73 * 74 * DESCRIPTION: Execute a control method or return the current value of an 75 * ACPI namespace object. 76 * 77 * MUTEX: Locks interpreter 78 * 79 ******************************************************************************/ 80 81 ACPI_STATUS 82 AcpiNsEvaluate ( 83 ACPI_EVALUATE_INFO *Info) 84 { 85 ACPI_STATUS Status; 86 87 88 ACPI_FUNCTION_TRACE (NsEvaluate); 89 90 91 if (!Info) 92 { 93 return_ACPI_STATUS (AE_BAD_PARAMETER); 94 } 95 96 if (!Info->Node) 97 { 98 /* 99 * Get the actual namespace node for the target object if we 100 * need to. Handles these cases: 101 * 102 * 1) Null node, valid pathname from root (absolute path) 103 * 2) Node and valid pathname (path relative to Node) 104 * 3) Node, Null pathname 105 */ 106 Status = AcpiNsGetNode (Info->PrefixNode, Info->RelativePathname, 107 ACPI_NS_NO_UPSEARCH, &Info->Node); 108 if (ACPI_FAILURE (Status)) 109 { 110 return_ACPI_STATUS (Status); 111 } 112 } 113 114 /* 115 * For a method alias, we must grab the actual method node so that 116 * proper scoping context will be established before execution. 117 */ 118 if (AcpiNsGetType (Info->Node) == ACPI_TYPE_LOCAL_METHOD_ALIAS) 119 { 120 Info->Node = ACPI_CAST_PTR ( 121 ACPI_NAMESPACE_NODE, Info->Node->Object); 122 } 123 124 /* Complete the info block initialization */ 125 126 Info->ReturnObject = NULL; 127 Info->NodeFlags = Info->Node->Flags; 128 Info->ObjDesc = AcpiNsGetAttachedObject (Info->Node); 129 130 ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "%s [%p] Value %p\n", 131 Info->RelativePathname, Info->Node, 132 AcpiNsGetAttachedObject (Info->Node))); 133 134 /* Get info if we have a predefined name (_HID, etc.) */ 135 136 Info->Predefined = AcpiUtMatchPredefinedMethod (Info->Node->Name.Ascii); 137 138 /* Get the full pathname to the object, for use in warning messages */ 139 140 Info->FullPathname = AcpiNsGetNormalizedPathname (Info->Node, TRUE); 141 if (!Info->FullPathname) 142 { 143 return_ACPI_STATUS (AE_NO_MEMORY); 144 } 145 146 /* Optional object evaluation log */ 147 148 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_EVALUATION, 149 "%-26s: %s (%s)\n", " Enter evaluation", 150 &Info->FullPathname[1], AcpiUtGetTypeName (Info->Node->Type))); 151 152 /* Count the number of arguments being passed in */ 153 154 Info->ParamCount = 0; 155 if (Info->Parameters) 156 { 157 while (Info->Parameters[Info->ParamCount]) 158 { 159 Info->ParamCount++; 160 } 161 162 /* Warn on impossible argument count */ 163 164 if (Info->ParamCount > ACPI_METHOD_NUM_ARGS) 165 { 166 ACPI_WARN_PREDEFINED ((AE_INFO, Info->FullPathname, ACPI_WARN_ALWAYS, 167 "Excess arguments (%u) - using only %u", 168 Info->ParamCount, ACPI_METHOD_NUM_ARGS)); 169 170 Info->ParamCount = ACPI_METHOD_NUM_ARGS; 171 } 172 } 173 174 /* 175 * For predefined names: Check that the declared argument count 176 * matches the ACPI spec -- otherwise this is a BIOS error. 177 */ 178 AcpiNsCheckAcpiCompliance (Info->FullPathname, Info->Node, 179 Info->Predefined); 180 181 /* 182 * For all names: Check that the incoming argument count for 183 * this method/object matches the actual ASL/AML definition. 184 */ 185 AcpiNsCheckArgumentCount (Info->FullPathname, Info->Node, 186 Info->ParamCount, Info->Predefined); 187 188 /* For predefined names: Typecheck all incoming arguments */ 189 190 AcpiNsCheckArgumentTypes (Info); 191 192 /* 193 * Three major evaluation cases: 194 * 195 * 1) Object types that cannot be evaluated by definition 196 * 2) The object is a control method -- execute it 197 * 3) The object is not a method -- just return it's current value 198 */ 199 switch (AcpiNsGetType (Info->Node)) 200 { 201 case ACPI_TYPE_ANY: 202 case ACPI_TYPE_DEVICE: 203 case ACPI_TYPE_EVENT: 204 case ACPI_TYPE_MUTEX: 205 case ACPI_TYPE_REGION: 206 case ACPI_TYPE_THERMAL: 207 case ACPI_TYPE_LOCAL_SCOPE: 208 /* 209 * 1) Disallow evaluation of these object types. For these, 210 * object evaluation is undefined. 211 */ 212 ACPI_ERROR ((AE_INFO, 213 "%s: This object type [%s] " 214 "never contains data and cannot be evaluated", 215 Info->FullPathname, AcpiUtGetTypeName (Info->Node->Type))); 216 217 Status = AE_TYPE; 218 goto Cleanup; 219 220 case ACPI_TYPE_METHOD: 221 /* 222 * 2) Object is a control method - execute it 223 */ 224 225 /* Verify that there is a method object associated with this node */ 226 227 if (!Info->ObjDesc) 228 { 229 ACPI_ERROR ((AE_INFO, "%s: Method has no attached sub-object", 230 Info->FullPathname)); 231 Status = AE_NULL_OBJECT; 232 goto Cleanup; 233 } 234 235 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, 236 "**** Execute method [%s] at AML address %p length %X\n", 237 Info->FullPathname, 238 Info->ObjDesc->Method.AmlStart + 1, 239 Info->ObjDesc->Method.AmlLength - 1)); 240 241 /* 242 * Any namespace deletion must acquire both the namespace and 243 * interpreter locks to ensure that no thread is using the portion of 244 * the namespace that is being deleted. 245 * 246 * Execute the method via the interpreter. The interpreter is locked 247 * here before calling into the AML parser 248 */ 249 AcpiExEnterInterpreter (); 250 Status = AcpiPsExecuteMethod (Info); 251 AcpiExExitInterpreter (); 252 break; 253 254 default: 255 /* 256 * 3) All other non-method objects -- get the current object value 257 */ 258 259 /* 260 * Some objects require additional resolution steps (e.g., the Node 261 * may be a field that must be read, etc.) -- we can't just grab 262 * the object out of the node. 263 * 264 * Use ResolveNodeToValue() to get the associated value. 265 * 266 * NOTE: we can get away with passing in NULL for a walk state because 267 * the Node is guaranteed to not be a reference to either a method 268 * local or a method argument (because this interface is never called 269 * from a running method.) 270 * 271 * Even though we do not directly invoke the interpreter for object 272 * resolution, we must lock it because we could access an OpRegion. 273 * The OpRegion access code assumes that the interpreter is locked. 274 */ 275 AcpiExEnterInterpreter (); 276 277 /* TBD: ResolveNodeToValue has a strange interface, fix */ 278 279 Info->ReturnObject = ACPI_CAST_PTR (ACPI_OPERAND_OBJECT, Info->Node); 280 281 Status = AcpiExResolveNodeToValue (ACPI_CAST_INDIRECT_PTR ( 282 ACPI_NAMESPACE_NODE, &Info->ReturnObject), NULL); 283 AcpiExExitInterpreter (); 284 285 if (ACPI_FAILURE (Status)) 286 { 287 Info->ReturnObject = NULL; 288 goto Cleanup; 289 } 290 291 ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "Returned object %p [%s]\n", 292 Info->ReturnObject, 293 AcpiUtGetObjectTypeName (Info->ReturnObject))); 294 295 Status = AE_CTRL_RETURN_VALUE; /* Always has a "return value" */ 296 break; 297 } 298 299 /* 300 * For predefined names, check the return value against the ACPI 301 * specification. Some incorrect return value types are repaired. 302 */ 303 (void) AcpiNsCheckReturnValue (Info->Node, Info, Info->ParamCount, 304 Status, &Info->ReturnObject); 305 306 /* Check if there is a return value that must be dealt with */ 307 308 if (Status == AE_CTRL_RETURN_VALUE) 309 { 310 /* If caller does not want the return value, delete it */ 311 312 if (Info->Flags & ACPI_IGNORE_RETURN_VALUE) 313 { 314 AcpiUtRemoveReference (Info->ReturnObject); 315 Info->ReturnObject = NULL; 316 } 317 318 /* Map AE_CTRL_RETURN_VALUE to AE_OK, we are done with it */ 319 320 Status = AE_OK; 321 } 322 else if (ACPI_FAILURE(Status)) 323 { 324 /* If ReturnObject exists, delete it */ 325 326 if (Info->ReturnObject) 327 { 328 AcpiUtRemoveReference (Info->ReturnObject); 329 Info->ReturnObject = NULL; 330 } 331 } 332 333 ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, 334 "*** Completed evaluation of object %s ***\n", 335 Info->RelativePathname)); 336 337 Cleanup: 338 /* Optional object evaluation log */ 339 340 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_EVALUATION, 341 "%-26s: %s\n", " Exit evaluation", 342 &Info->FullPathname[1])); 343 344 /* 345 * Namespace was unlocked by the handling AcpiNs* function, so we 346 * just free the pathname and return 347 */ 348 ACPI_FREE (Info->FullPathname); 349 Info->FullPathname = NULL; 350 return_ACPI_STATUS (Status); 351 } 352