nseval.c revision 128212
1/*******************************************************************************
2 *
3 * Module Name: nseval - Object evaluation interfaces -- includes control
4 *                       method lookup and execution.
5 *              $Revision: 125 $
6 *
7 ******************************************************************************/
8
9/******************************************************************************
10 *
11 * 1. Copyright Notice
12 *
13 * Some or all of this work - Copyright (c) 1999 - 2004, Intel Corp.
14 * All rights reserved.
15 *
16 * 2. License
17 *
18 * 2.1. This is your license from Intel Corp. under its intellectual property
19 * rights.  You may have additional license terms from the party that provided
20 * you this software, covering your right to use that party's intellectual
21 * property rights.
22 *
23 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
24 * copy of the source code appearing in this file ("Covered Code") an
25 * irrevocable, perpetual, worldwide license under Intel's copyrights in the
26 * base code distributed originally by Intel ("Original Intel Code") to copy,
27 * make derivatives, distribute, use and display any portion of the Covered
28 * Code in any form, with the right to sublicense such rights; and
29 *
30 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
31 * license (with the right to sublicense), under only those claims of Intel
32 * patents that are infringed by the Original Intel Code, to make, use, sell,
33 * offer to sell, and import the Covered Code and derivative works thereof
34 * solely to the minimum extent necessary to exercise the above copyright
35 * license, and in no event shall the patent license extend to any additions
36 * to or modifications of the Original Intel Code.  No other license or right
37 * is granted directly or by implication, estoppel or otherwise;
38 *
39 * The above copyright and patent license is granted only if the following
40 * conditions are met:
41 *
42 * 3. Conditions
43 *
44 * 3.1. Redistribution of Source with Rights to Further Distribute Source.
45 * Redistribution of source code of any substantial portion of the Covered
46 * Code or modification with rights to further distribute source must include
47 * the above Copyright Notice, the above License, this list of Conditions,
48 * and the following Disclaimer and Export Compliance provision.  In addition,
49 * Licensee must cause all Covered Code to which Licensee contributes to
50 * contain a file documenting the changes Licensee made to create that Covered
51 * Code and the date of any change.  Licensee must include in that file the
52 * documentation of any changes made by any predecessor Licensee.  Licensee
53 * must include a prominent statement that the modification is derived,
54 * directly or indirectly, from Original Intel Code.
55 *
56 * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
57 * Redistribution of source code of any substantial portion of the Covered
58 * Code or modification without rights to further distribute source must
59 * include the following Disclaimer and Export Compliance provision in the
60 * documentation and/or other materials provided with distribution.  In
61 * addition, Licensee may not authorize further sublicense of source of any
62 * portion of the Covered Code, and must include terms to the effect that the
63 * license from Licensee to its licensee is limited to the intellectual
64 * property embodied in the software Licensee provides to its licensee, and
65 * not to intellectual property embodied in modifications its licensee may
66 * make.
67
68 *
69 * 3.3. Redistribution of Executable. Redistribution in executable form of any
70 * substantial portion of the Covered Code or modification must reproduce the
71 * above Copyright Notice, and the following Disclaimer and Export Compliance
72 * provision in the documentation and/or other materials provided with the
73 * distribution.
74 *
75 * 3.4. Intel retains all right, title, and interest in and to the Original
76 * Intel Code.
77 *
78 * 3.5. Neither the name Intel nor any other trademark owned or controlled by
79 * Intel shall be used in advertising or otherwise to promote the sale, use or
80 * other dealings in products derived from or relating to the Covered Code
81 * without prior written authorization from Intel.
82 *
83 * 4. Disclaimer and Export Compliance
84 *
85 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
86 * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
87 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
88 * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
89 * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
90 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
91 * PARTICULAR PURPOSE.
92 *
93 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
94 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
95 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
96 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
97 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
98 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
99 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
100 * LIMITED REMEDY.
101 *
102 * 4.3. Licensee shall not export, either directly or indirectly, any of this
103 * software or system incorporating such software without first obtaining any
104 * required license or other approval from the U. S. Department of Commerce or
105 * any other agency or department of the United States Government.  In the
106 * event Licensee exports any such software from the United States or
107 * re-exports any such software from a foreign destination, Licensee shall
108 * ensure that the distribution and export/re-export of the software is in
109 * compliance with all laws, regulations, orders, or other restrictions of the
110 * U.S. Export Administration Regulations. Licensee agrees that neither it nor
111 * any of its subsidiaries will export/re-export any technical data, process,
112 * software, or service, directly or indirectly, to any country for which the
113 * United States government or any agency thereof requires an export license,
114 * other governmental approval, or letter of assurance, without first obtaining
115 * such license, approval or letter.
116 *
117 *****************************************************************************/
118
119#define __NSEVAL_C__
120
121#include "acpi.h"
122#include "acparser.h"
123#include "acinterp.h"
124#include "acnamesp.h"
125
126
127#define _COMPONENT          ACPI_NAMESPACE
128        ACPI_MODULE_NAME    ("nseval")
129
130
131/*******************************************************************************
132 *
133 * FUNCTION:    AcpiNsEvaluateRelative
134 *
135 * PARAMETERS:  Handle              - The relative containing object
136 *              Pathname            - Name of method to execute, If NULL, the
137 *                                    handle is the object to execute
138 *              Params              - List of parameters to pass to the method,
139 *                                    terminated by NULL.  Params itself may be
140 *                                    NULL if no parameters are being passed.
141 *              ReturnObject        - Where to put method's return value (if
142 *                                    any).  If NULL, no value is returned.
143 *
144 * RETURN:      Status
145 *
146 * DESCRIPTION: Find and execute the requested method using the handle as a
147 *              scope
148 *
149 * MUTEX:       Locks Namespace
150 *
151 ******************************************************************************/
152
153ACPI_STATUS
154AcpiNsEvaluateRelative (
155    ACPI_NAMESPACE_NODE     *Handle,
156    char                    *Pathname,
157    ACPI_OPERAND_OBJECT     **Params,
158    ACPI_OPERAND_OBJECT     **ReturnObject)
159{
160    ACPI_STATUS             Status;
161    ACPI_NAMESPACE_NODE     *PrefixNode;
162    ACPI_NAMESPACE_NODE     *Node = NULL;
163    ACPI_GENERIC_STATE      *ScopeInfo;
164    char                    *InternalPath = NULL;
165
166
167    ACPI_FUNCTION_TRACE ("NsEvaluateRelative");
168
169
170    /*
171     * Must have a valid object handle
172     */
173    if (!Handle)
174    {
175        return_ACPI_STATUS (AE_BAD_PARAMETER);
176    }
177
178    /* Build an internal name string for the method */
179
180    Status = AcpiNsInternalizeName (Pathname, &InternalPath);
181    if (ACPI_FAILURE (Status))
182    {
183        return_ACPI_STATUS (Status);
184    }
185
186    ScopeInfo = AcpiUtCreateGenericState ();
187    if (!ScopeInfo)
188    {
189        goto Cleanup1;
190    }
191
192    /* Get the prefix handle and Node */
193
194    Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
195    if (ACPI_FAILURE (Status))
196    {
197        goto Cleanup;
198    }
199
200    PrefixNode = AcpiNsMapHandleToNode (Handle);
201    if (!PrefixNode)
202    {
203        (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
204        Status = AE_BAD_PARAMETER;
205        goto Cleanup;
206    }
207
208    /* Lookup the name in the namespace */
209
210    ScopeInfo->Scope.Node = PrefixNode;
211    Status = AcpiNsLookup (ScopeInfo, InternalPath, ACPI_TYPE_ANY,
212                            ACPI_IMODE_EXECUTE, ACPI_NS_NO_UPSEARCH, NULL,
213                            &Node);
214
215    (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
216
217    if (ACPI_FAILURE (Status))
218    {
219        ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "Object [%s] not found [%s]\n",
220            Pathname, AcpiFormatException (Status)));
221        goto Cleanup;
222    }
223
224    /*
225     * Now that we have a handle to the object, we can attempt
226     * to evaluate it.
227     */
228    ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "%s [%p] Value %p\n",
229        Pathname, Node, AcpiNsGetAttachedObject (Node)));
230
231    Status = AcpiNsEvaluateByHandle (Node, Params, ReturnObject);
232
233    ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "*** Completed eval of object %s ***\n",
234        Pathname));
235
236Cleanup:
237    AcpiUtDeleteGenericState (ScopeInfo);
238
239Cleanup1:
240    ACPI_MEM_FREE (InternalPath);
241    return_ACPI_STATUS (Status);
242}
243
244
245/*******************************************************************************
246 *
247 * FUNCTION:    AcpiNsEvaluateByName
248 *
249 * PARAMETERS:  Pathname            - Fully qualified pathname to the object
250 *              ReturnObject        - Where to put method's return value (if
251 *                                    any).  If NULL, no value is returned.
252 *              Params              - List of parameters to pass to the method,
253 *                                    terminated by NULL.  Params itself may be
254 *                                    NULL if no parameters are being passed.
255 *
256 * RETURN:      Status
257 *
258 * DESCRIPTION: Find and execute the requested method passing the given
259 *              parameters
260 *
261 * MUTEX:       Locks Namespace
262 *
263 ******************************************************************************/
264
265ACPI_STATUS
266AcpiNsEvaluateByName (
267    char                    *Pathname,
268    ACPI_OPERAND_OBJECT     **Params,
269    ACPI_OPERAND_OBJECT     **ReturnObject)
270{
271    ACPI_STATUS             Status;
272    ACPI_NAMESPACE_NODE     *Node = NULL;
273    char                    *InternalPath = NULL;
274
275
276    ACPI_FUNCTION_TRACE ("NsEvaluateByName");
277
278
279    /* Build an internal name string for the method */
280
281    Status = AcpiNsInternalizeName (Pathname, &InternalPath);
282    if (ACPI_FAILURE (Status))
283    {
284        return_ACPI_STATUS (Status);
285    }
286
287    Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
288    if (ACPI_FAILURE (Status))
289    {
290        goto Cleanup;
291    }
292
293    /* Lookup the name in the namespace */
294
295    Status = AcpiNsLookup (NULL, InternalPath, ACPI_TYPE_ANY,
296                            ACPI_IMODE_EXECUTE, ACPI_NS_NO_UPSEARCH, NULL,
297                            &Node);
298
299    (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
300
301    if (ACPI_FAILURE (Status))
302    {
303        ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "Object at [%s] was not found, status=%.4X\n",
304            Pathname, Status));
305        goto Cleanup;
306    }
307
308    /*
309     * Now that we have a handle to the object, we can attempt
310     * to evaluate it.
311     */
312    ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "%s [%p] Value %p\n",
313        Pathname, Node, AcpiNsGetAttachedObject (Node)));
314
315    Status = AcpiNsEvaluateByHandle (Node, Params, ReturnObject);
316
317    ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "*** Completed eval of object %s ***\n",
318        Pathname));
319
320
321Cleanup:
322
323    /* Cleanup */
324
325    if (InternalPath)
326    {
327        ACPI_MEM_FREE (InternalPath);
328    }
329
330    return_ACPI_STATUS (Status);
331}
332
333
334/*******************************************************************************
335 *
336 * FUNCTION:    AcpiNsEvaluateByHandle
337 *
338 * PARAMETERS:  Handle              - Method Node to execute
339 *              Params              - List of parameters to pass to the method,
340 *                                    terminated by NULL.  Params itself may be
341 *                                    NULL if no parameters are being passed.
342 *              ReturnObject        - Where to put method's return value (if
343 *                                    any).  If NULL, no value is returned.
344 *
345 * RETURN:      Status
346 *
347 * DESCRIPTION: Execute the requested method passing the given parameters
348 *
349 * MUTEX:       Locks Namespace
350 *
351 ******************************************************************************/
352
353ACPI_STATUS
354AcpiNsEvaluateByHandle (
355    ACPI_NAMESPACE_NODE     *Handle,
356    ACPI_OPERAND_OBJECT     **Params,
357    ACPI_OPERAND_OBJECT     **ReturnObject)
358{
359    ACPI_NAMESPACE_NODE     *Node;
360    ACPI_STATUS             Status;
361    ACPI_OPERAND_OBJECT     *LocalReturnObject;
362
363
364    ACPI_FUNCTION_TRACE ("NsEvaluateByHandle");
365
366
367    /* Check if namespace has been initialized */
368
369    if (!AcpiGbl_RootNode)
370    {
371        return_ACPI_STATUS (AE_NO_NAMESPACE);
372    }
373
374    /* Parameter Validation */
375
376    if (!Handle)
377    {
378        return_ACPI_STATUS (AE_BAD_PARAMETER);
379    }
380
381    if (ReturnObject)
382    {
383        /* Initialize the return value to an invalid object */
384
385        *ReturnObject = NULL;
386    }
387
388    /* Get the prefix handle and Node */
389
390    Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
391    if (ACPI_FAILURE (Status))
392    {
393        return_ACPI_STATUS (Status);
394    }
395
396    Node = AcpiNsMapHandleToNode (Handle);
397    if (!Node)
398    {
399        (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
400        return_ACPI_STATUS (AE_BAD_PARAMETER);
401    }
402
403    /*
404     * For a method alias, we must grab the actual method node
405     * so that proper scoping context will be established
406     * before execution.
407     */
408    if (AcpiNsGetType (Node) == ACPI_TYPE_LOCAL_METHOD_ALIAS)
409    {
410        Node = ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, Node->Object);
411    }
412
413    /*
414     * Two major cases here:
415     * 1) The object is an actual control method -- execute it.
416     * 2) The object is not a method -- just return it's current
417     *      value
418     *
419     * In both cases, the namespace is unlocked by the
420     *  AcpiNs* procedure
421     */
422    if (AcpiNsGetType (Node) == ACPI_TYPE_METHOD)
423    {
424        /*
425         * Case 1) We have an actual control method to execute
426         */
427        Status = AcpiNsExecuteControlMethod (Node, Params,
428                                            &LocalReturnObject);
429    }
430    else
431    {
432        /*
433         * Case 2) Object is NOT a method, just return its
434         * current value
435         */
436        Status = AcpiNsGetObjectValue (Node, &LocalReturnObject);
437    }
438
439    /*
440     * Check if there is a return value on the stack that must
441     * be dealt with
442     */
443    if (Status == AE_CTRL_RETURN_VALUE)
444    {
445        /*
446         * If the Method returned a value and the caller
447         * provided a place to store a returned value, Copy
448         * the returned value to the object descriptor provided
449         * by the caller.
450         */
451        if (ReturnObject)
452        {
453            /*
454             * Valid return object, copy the pointer to
455             * the returned object
456             */
457            *ReturnObject = LocalReturnObject;
458        }
459
460        /* Map AE_CTRL_RETURN_VALUE to AE_OK, we are done with it */
461
462        Status = AE_OK;
463    }
464
465    /*
466     * Namespace was unlocked by the handling AcpiNs* function,
467     * so we just return
468     */
469    return_ACPI_STATUS (Status);
470}
471
472
473/*******************************************************************************
474 *
475 * FUNCTION:    AcpiNsExecuteControlMethod
476 *
477 * PARAMETERS:  MethodNode          - The method to execute
478 *              Params              - List of parameters to pass to the method,
479 *                                    terminated by NULL.  Params itself may be
480 *                                    NULL if no parameters are being passed.
481 *              ReturnObjDesc       - List of result objects to be returned
482 *                                    from the method.
483 *
484 * RETURN:      Status
485 *
486 * DESCRIPTION: Execute the requested method passing the given parameters
487 *
488 * MUTEX:       Assumes namespace is locked
489 *
490 ******************************************************************************/
491
492ACPI_STATUS
493AcpiNsExecuteControlMethod (
494    ACPI_NAMESPACE_NODE     *MethodNode,
495    ACPI_OPERAND_OBJECT     **Params,
496    ACPI_OPERAND_OBJECT     **ReturnObjDesc)
497{
498    ACPI_STATUS             Status;
499    ACPI_OPERAND_OBJECT     *ObjDesc;
500
501
502    ACPI_FUNCTION_TRACE ("NsExecuteControlMethod");
503
504
505    /* Verify that there is a method associated with this object */
506
507    ObjDesc = AcpiNsGetAttachedObject (MethodNode);
508    if (!ObjDesc)
509    {
510        ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "No attached method object\n"));
511
512        (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
513        return_ACPI_STATUS (AE_NULL_OBJECT);
514    }
515
516    ACPI_DUMP_PATHNAME (MethodNode, "Execute Method:",
517        ACPI_LV_INFO, _COMPONENT);
518
519    ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Method at AML address %p Length %X\n",
520        ObjDesc->Method.AmlStart + 1, ObjDesc->Method.AmlLength - 1));
521
522    /*
523     * Unlock the namespace before execution.  This allows namespace access
524     * via the external Acpi* interfaces while a method is being executed.
525     * However, any namespace deletion must acquire both the namespace and
526     * interpreter locks to ensure that no thread is using the portion of the
527     * namespace that is being deleted.
528     */
529    Status = AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
530    if (ACPI_FAILURE (Status))
531    {
532        return_ACPI_STATUS (Status);
533    }
534
535    /*
536     * Execute the method via the interpreter.  The interpreter is locked
537     * here before calling into the AML parser
538     */
539    Status = AcpiExEnterInterpreter ();
540    if (ACPI_FAILURE (Status))
541    {
542        return_ACPI_STATUS (Status);
543    }
544
545    Status = AcpiPsxExecute (MethodNode, Params, ReturnObjDesc);
546    AcpiExExitInterpreter ();
547
548    return_ACPI_STATUS (Status);
549}
550
551
552/*******************************************************************************
553 *
554 * FUNCTION:    AcpiNsGetObjectValue
555 *
556 * PARAMETERS:  Node                - The object
557 *              ReturnObjDesc       - Where the objects value is returned
558 *
559 * RETURN:      Status
560 *
561 * DESCRIPTION: Return the current value of the object
562 *
563 * MUTEX:       Assumes namespace is locked, leaves namespace unlocked
564 *
565 ******************************************************************************/
566
567ACPI_STATUS
568AcpiNsGetObjectValue (
569    ACPI_NAMESPACE_NODE     *Node,
570    ACPI_OPERAND_OBJECT     **ReturnObjDesc)
571{
572    ACPI_STATUS             Status = AE_OK;
573    ACPI_NAMESPACE_NODE     *ResolvedNode = Node;
574
575
576    ACPI_FUNCTION_TRACE ("NsGetObjectValue");
577
578
579    /*
580     * Objects require additional resolution steps (e.g., the
581     * Node may be a field that must be read, etc.) -- we can't just grab
582     * the object out of the node.
583     */
584
585    /*
586     * Use ResolveNodeToValue() to get the associated value.  This call
587     * always deletes ObjDesc (allocated above).
588     *
589     * NOTE: we can get away with passing in NULL for a walk state
590     * because ObjDesc is guaranteed to not be a reference to either
591     * a method local or a method argument (because this interface can only be
592     * called from the AcpiEvaluate external interface, never called from
593     * a running control method.)
594     *
595     * Even though we do not directly invoke the interpreter
596     * for this, we must enter it because we could access an opregion.
597     * The opregion access code assumes that the interpreter
598     * is locked.
599     *
600     * We must release the namespace lock before entering the
601     * intepreter.
602     */
603    Status = AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
604    if (ACPI_FAILURE (Status))
605    {
606        return_ACPI_STATUS (Status);
607    }
608
609    Status = AcpiExEnterInterpreter ();
610    if (ACPI_SUCCESS (Status))
611    {
612        Status = AcpiExResolveNodeToValue (&ResolvedNode, NULL);
613        /*
614         * If AcpiExResolveNodeToValue() succeeded, the return value was
615         * placed in ResolvedNode.
616         */
617        AcpiExExitInterpreter ();
618
619        if (ACPI_SUCCESS (Status))
620        {
621            Status = AE_CTRL_RETURN_VALUE;
622            *ReturnObjDesc = ACPI_CAST_PTR (ACPI_OPERAND_OBJECT, ResolvedNode);
623            ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "Returning object %p [%s]\n",
624                *ReturnObjDesc, AcpiUtGetObjectTypeName (*ReturnObjDesc)));
625        }
626    }
627
628    /* Namespace is unlocked */
629
630    return_ACPI_STATUS (Status);
631}
632
633