1 /*******************************************************************************
3 * Module Name: nseval - Object evaluation, includes control method execution
5 ******************************************************************************/
8 * Copyright (C) 2000 - 2012, Intel Corp.
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
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.
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.
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 MERCHANTIBILITY 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.
53 #define _COMPONENT ACPI_NAMESPACE
54 ACPI_MODULE_NAME ("nseval")
56 /* Local prototypes */
59 AcpiNsExecModuleCode (
60 ACPI_OPERAND_OBJECT *MethodObj,
61 ACPI_EVALUATE_INFO *Info);
64 /*******************************************************************************
66 * FUNCTION: AcpiNsEvaluate
68 * PARAMETERS: Info - Evaluation info block, contains:
69 * PrefixNode - Prefix or Method/Object Node to execute
70 * Pathname - Name of method to execute, If NULL, the
71 * Node is the object to execute
72 * Parameters - List of parameters to pass to the method,
73 * terminated by NULL. Params itself may be
74 * NULL if no parameters are being passed.
75 * ReturnObject - Where to put method's return value (if
76 * any). If NULL, no value is returned.
77 * ParameterType - Type of Parameter list
78 * ReturnObject - Where to put method's return value (if
79 * any). If NULL, no value is returned.
80 * Flags - ACPI_IGNORE_RETURN_VALUE to delete return
84 * DESCRIPTION: Execute a control method or return the current value of an
85 * ACPI namespace object.
87 * MUTEX: Locks interpreter
89 ******************************************************************************/
93 ACPI_EVALUATE_INFO *Info)
96 ACPI_NAMESPACE_NODE *Node;
99 ACPI_FUNCTION_TRACE (NsEvaluate);
104 return_ACPI_STATUS (AE_BAD_PARAMETER);
107 /* Initialize the return value to an invalid object */
109 Info->ReturnObject = NULL;
110 Info->ParamCount = 0;
113 * Get the actual namespace node for the target object. Handles these cases:
115 * 1) Null node, Pathname (absolute path)
116 * 2) Node, Pathname (path relative to Node)
117 * 3) Node, Null Pathname
119 Status = AcpiNsGetNode (Info->PrefixNode, Info->Pathname,
120 ACPI_NS_NO_UPSEARCH, &Info->ResolvedNode);
121 if (ACPI_FAILURE (Status))
123 return_ACPI_STATUS (Status);
127 * For a method alias, we must grab the actual method node so that proper
128 * scoping context will be established before execution.
130 if (AcpiNsGetType (Info->ResolvedNode) == ACPI_TYPE_LOCAL_METHOD_ALIAS)
133 ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, Info->ResolvedNode->Object);
136 ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "%s [%p] Value %p\n", Info->Pathname,
137 Info->ResolvedNode, AcpiNsGetAttachedObject (Info->ResolvedNode)));
139 Node = Info->ResolvedNode;
142 * Two major cases here:
144 * 1) The object is a control method -- execute it
145 * 2) The object is not a method -- just return it's current value
147 if (AcpiNsGetType (Info->ResolvedNode) == ACPI_TYPE_METHOD)
150 * 1) Object is a control method - execute it
153 /* Verify that there is a method object associated with this node */
155 Info->ObjDesc = AcpiNsGetAttachedObject (Info->ResolvedNode);
158 ACPI_ERROR ((AE_INFO, "Control method has no attached sub-object"));
159 return_ACPI_STATUS (AE_NULL_OBJECT);
162 /* Count the number of arguments being passed to the method */
164 if (Info->Parameters)
166 while (Info->Parameters[Info->ParamCount])
168 if (Info->ParamCount > ACPI_METHOD_MAX_ARG)
170 return_ACPI_STATUS (AE_LIMIT);
176 ACPI_DUMP_PATHNAME (Info->ResolvedNode, "ACPI: Execute Method",
177 ACPI_LV_INFO, _COMPONENT);
179 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC,
180 "Method at AML address %p Length %X\n",
181 Info->ObjDesc->Method.AmlStart + 1,
182 Info->ObjDesc->Method.AmlLength - 1));
185 * Any namespace deletion must acquire both the namespace and
186 * interpreter locks to ensure that no thread is using the portion of
187 * the namespace that is being deleted.
189 * Execute the method via the interpreter. The interpreter is locked
190 * here before calling into the AML parser
192 AcpiExEnterInterpreter ();
193 Status = AcpiPsExecuteMethod (Info);
194 AcpiExExitInterpreter ();
199 * 2) Object is not a method, return its current value
201 * Disallow certain object types. For these, "evaluation" is undefined.
203 switch (Info->ResolvedNode->Type)
205 case ACPI_TYPE_DEVICE:
206 case ACPI_TYPE_EVENT:
207 case ACPI_TYPE_MUTEX:
208 case ACPI_TYPE_REGION:
209 case ACPI_TYPE_THERMAL:
210 case ACPI_TYPE_LOCAL_SCOPE:
212 ACPI_ERROR ((AE_INFO,
213 "[%4.4s] Evaluation of object type [%s] is not supported",
214 Info->ResolvedNode->Name.Ascii,
215 AcpiUtGetTypeName (Info->ResolvedNode->Type)));
217 return_ACPI_STATUS (AE_TYPE);
224 * Objects require additional resolution steps (e.g., the Node may be
225 * a field that must be read, etc.) -- we can't just grab the object
228 * Use ResolveNodeToValue() to get the associated value.
230 * NOTE: we can get away with passing in NULL for a walk state because
231 * ResolvedNode is guaranteed to not be a reference to either a method
232 * local or a method argument (because this interface is never called
233 * from a running method.)
235 * Even though we do not directly invoke the interpreter for object
236 * resolution, we must lock it because we could access an opregion.
237 * The opregion access code assumes that the interpreter is locked.
239 AcpiExEnterInterpreter ();
241 /* Function has a strange interface */
243 Status = AcpiExResolveNodeToValue (&Info->ResolvedNode, NULL);
244 AcpiExExitInterpreter ();
247 * If AcpiExResolveNodeToValue() succeeded, the return value was placed
250 if (ACPI_SUCCESS (Status))
252 Status = AE_CTRL_RETURN_VALUE;
254 ACPI_CAST_PTR (ACPI_OPERAND_OBJECT, Info->ResolvedNode);
256 ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "Returning object %p [%s]\n",
258 AcpiUtGetObjectTypeName (Info->ReturnObject)));
263 * Check input argument count against the ASL-defined count for a method.
264 * Also check predefined names: argument count and return value against
265 * the ACPI specification. Some incorrect return value types are repaired.
267 (void) AcpiNsCheckPredefinedNames (Node, Info->ParamCount,
268 Status, &Info->ReturnObject);
270 /* Check if there is a return value that must be dealt with */
272 if (Status == AE_CTRL_RETURN_VALUE)
274 /* If caller does not want the return value, delete it */
276 if (Info->Flags & ACPI_IGNORE_RETURN_VALUE)
278 AcpiUtRemoveReference (Info->ReturnObject);
279 Info->ReturnObject = NULL;
282 /* Map AE_CTRL_RETURN_VALUE to AE_OK, we are done with it */
287 ACPI_DEBUG_PRINT ((ACPI_DB_NAMES,
288 "*** Completed evaluation of object %s ***\n", Info->Pathname));
291 * Namespace was unlocked by the handling AcpiNs* function, so we
294 return_ACPI_STATUS (Status);
298 /*******************************************************************************
300 * FUNCTION: AcpiNsExecModuleCodeList
304 * RETURN: None. Exceptions during method execution are ignored, since
305 * we cannot abort a table load.
307 * DESCRIPTION: Execute all elements of the global module-level code list.
308 * Each element is executed as a single control method.
310 ******************************************************************************/
313 AcpiNsExecModuleCodeList (
316 ACPI_OPERAND_OBJECT *Prev;
317 ACPI_OPERAND_OBJECT *Next;
318 ACPI_EVALUATE_INFO *Info;
319 UINT32 MethodCount = 0;
322 ACPI_FUNCTION_TRACE (NsExecModuleCodeList);
325 /* Exit now if the list is empty */
327 Next = AcpiGbl_ModuleCodeList;
333 /* Allocate the evaluation information block */
335 Info = ACPI_ALLOCATE (sizeof (ACPI_EVALUATE_INFO));
341 /* Walk the list, executing each "method" */
346 Next = Next->Method.Mutex;
348 /* Clear the link field and execute the method */
350 Prev->Method.Mutex = NULL;
351 AcpiNsExecModuleCode (Prev, Info);
354 /* Delete the (temporary) method object */
356 AcpiUtRemoveReference (Prev);
360 "Executed %u blocks of module-level executable AML code",
364 AcpiGbl_ModuleCodeList = NULL;
369 /*******************************************************************************
371 * FUNCTION: AcpiNsExecModuleCode
373 * PARAMETERS: MethodObj - Object container for the module-level code
374 * Info - Info block for method evaluation
376 * RETURN: None. Exceptions during method execution are ignored, since
377 * we cannot abort a table load.
379 * DESCRIPTION: Execute a control method containing a block of module-level
380 * executable AML code. The control method is temporarily
381 * installed to the root node, then evaluated.
383 ******************************************************************************/
386 AcpiNsExecModuleCode (
387 ACPI_OPERAND_OBJECT *MethodObj,
388 ACPI_EVALUATE_INFO *Info)
390 ACPI_OPERAND_OBJECT *ParentObj;
391 ACPI_NAMESPACE_NODE *ParentNode;
392 ACPI_OBJECT_TYPE Type;
396 ACPI_FUNCTION_TRACE (NsExecModuleCode);
400 * Get the parent node. We cheat by using the NextObject field
401 * of the method object descriptor.
403 ParentNode = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE,
404 MethodObj->Method.NextObject);
405 Type = AcpiNsGetType (ParentNode);
408 * Get the region handler and save it in the method object. We may need
409 * this if an operation region declaration causes a _REG method to be run.
411 * We can't do this in AcpiPsLinkModuleCode because
412 * AcpiGbl_RootNode->Object is NULL at PASS1.
414 if ((Type == ACPI_TYPE_DEVICE) && ParentNode->Object)
416 MethodObj->Method.Dispatch.Handler =
417 ParentNode->Object->Device.Handler;
420 /* Must clear NextObject (AcpiNsAttachObject needs the field) */
422 MethodObj->Method.NextObject = NULL;
424 /* Initialize the evaluation information block */
426 ACPI_MEMSET (Info, 0, sizeof (ACPI_EVALUATE_INFO));
427 Info->PrefixNode = ParentNode;
430 * Get the currently attached parent object. Add a reference, because the
431 * ref count will be decreased when the method object is installed to
434 ParentObj = AcpiNsGetAttachedObject (ParentNode);
437 AcpiUtAddReference (ParentObj);
440 /* Install the method (module-level code) in the parent node */
442 Status = AcpiNsAttachObject (ParentNode, MethodObj,
444 if (ACPI_FAILURE (Status))
449 /* Execute the parent node as a control method */
451 Status = AcpiNsEvaluate (Info);
453 ACPI_DEBUG_PRINT ((ACPI_DB_INIT, "Executed module-level code at %p\n",
454 MethodObj->Method.AmlStart));
456 /* Delete a possible implicit return value (in slack mode) */
458 if (Info->ReturnObject)
460 AcpiUtRemoveReference (Info->ReturnObject);
463 /* Detach the temporary method object */
465 AcpiNsDetachObject (ParentNode);
467 /* Restore the original parent object */
471 Status = AcpiNsAttachObject (ParentNode, ParentObj, Type);
475 ParentNode->Type = (UINT8) Type;
481 AcpiUtRemoveReference (ParentObj);