2 /******************************************************************************
4 * Module Name: exresolv - AML Interpreter object resolution
6 *****************************************************************************/
9 * Copyright (C) 2000 - 2011, Intel Corp.
10 * All rights reserved.
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions, and the following disclaimer,
17 * without modification.
18 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
19 * substantially similar to the "NO WARRANTY" disclaimer below
20 * ("Disclaimer") and any redistribution must be conditioned upon
21 * including a substantially similar Disclaimer requirement for further
22 * binary redistribution.
23 * 3. Neither the names of the above-listed copyright holders nor the names
24 * of any contributors may be used to endorse or promote products derived
25 * from this software without specific prior written permission.
27 * Alternatively, this software may be distributed under the terms of the
28 * GNU General Public License ("GPL") version 2 as published by the Free
29 * Software Foundation.
32 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
33 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
34 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
35 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
36 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
38 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
39 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
40 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
41 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
42 * POSSIBILITY OF SUCH DAMAGES.
45 #define __EXRESOLV_C__
47 #include <contrib/dev/acpica/include/acpi.h>
48 #include <contrib/dev/acpica/include/accommon.h>
49 #include <contrib/dev/acpica/include/amlcode.h>
50 #include <contrib/dev/acpica/include/acdispat.h>
51 #include <contrib/dev/acpica/include/acinterp.h>
52 #include <contrib/dev/acpica/include/acnamesp.h>
55 #define _COMPONENT ACPI_EXECUTER
56 ACPI_MODULE_NAME ("exresolv")
58 /* Local prototypes */
61 AcpiExResolveObjectToValue (
62 ACPI_OPERAND_OBJECT **StackPtr,
63 ACPI_WALK_STATE *WalkState);
66 /*******************************************************************************
68 * FUNCTION: AcpiExResolveToValue
70 * PARAMETERS: **StackPtr - Points to entry on ObjStack, which can
71 * be either an (ACPI_OPERAND_OBJECT *)
73 * WalkState - Current method state
77 * DESCRIPTION: Convert Reference objects to values
79 ******************************************************************************/
82 AcpiExResolveToValue (
83 ACPI_OPERAND_OBJECT **StackPtr,
84 ACPI_WALK_STATE *WalkState)
89 ACPI_FUNCTION_TRACE_PTR (ExResolveToValue, StackPtr);
92 if (!StackPtr || !*StackPtr)
94 ACPI_ERROR ((AE_INFO, "Internal - null pointer"));
95 return_ACPI_STATUS (AE_AML_NO_OPERAND);
99 * The entity pointed to by the StackPtr can be either
100 * 1) A valid ACPI_OPERAND_OBJECT, or
101 * 2) A ACPI_NAMESPACE_NODE (NamedObj)
103 if (ACPI_GET_DESCRIPTOR_TYPE (*StackPtr) == ACPI_DESC_TYPE_OPERAND)
105 Status = AcpiExResolveObjectToValue (StackPtr, WalkState);
106 if (ACPI_FAILURE (Status))
108 return_ACPI_STATUS (Status);
113 ACPI_ERROR ((AE_INFO, "Internal - null pointer"));
114 return_ACPI_STATUS (AE_AML_NO_OPERAND);
119 * Object on the stack may have changed if AcpiExResolveObjectToValue()
120 * was called (i.e., we can't use an _else_ here.)
122 if (ACPI_GET_DESCRIPTOR_TYPE (*StackPtr) == ACPI_DESC_TYPE_NAMED)
124 Status = AcpiExResolveNodeToValue (
125 ACPI_CAST_INDIRECT_PTR (ACPI_NAMESPACE_NODE, StackPtr),
127 if (ACPI_FAILURE (Status))
129 return_ACPI_STATUS (Status);
133 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Resolved object %p\n", *StackPtr));
134 return_ACPI_STATUS (AE_OK);
138 /*******************************************************************************
140 * FUNCTION: AcpiExResolveObjectToValue
142 * PARAMETERS: StackPtr - Pointer to an internal object
143 * WalkState - Current method state
147 * DESCRIPTION: Retrieve the value from an internal object. The Reference type
148 * uses the associated AML opcode to determine the value.
150 ******************************************************************************/
153 AcpiExResolveObjectToValue (
154 ACPI_OPERAND_OBJECT **StackPtr,
155 ACPI_WALK_STATE *WalkState)
157 ACPI_STATUS Status = AE_OK;
158 ACPI_OPERAND_OBJECT *StackDesc;
159 ACPI_OPERAND_OBJECT *ObjDesc = NULL;
163 ACPI_FUNCTION_TRACE (ExResolveObjectToValue);
166 StackDesc = *StackPtr;
168 /* This is an ACPI_OPERAND_OBJECT */
170 switch (StackDesc->Common.Type)
172 case ACPI_TYPE_LOCAL_REFERENCE:
174 RefType = StackDesc->Reference.Class;
178 case ACPI_REFCLASS_LOCAL:
179 case ACPI_REFCLASS_ARG:
182 * Get the local from the method's state info
183 * Note: this increments the local's object reference count
185 Status = AcpiDsMethodDataGetValue (RefType,
186 StackDesc->Reference.Value, WalkState, &ObjDesc);
187 if (ACPI_FAILURE (Status))
189 return_ACPI_STATUS (Status);
192 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[Arg/Local %X] ValueObj is %p\n",
193 StackDesc->Reference.Value, ObjDesc));
196 * Now we can delete the original Reference Object and
197 * replace it with the resolved value
199 AcpiUtRemoveReference (StackDesc);
204 case ACPI_REFCLASS_INDEX:
206 switch (StackDesc->Reference.TargetType)
208 case ACPI_TYPE_BUFFER_FIELD:
210 /* Just return - do not dereference */
214 case ACPI_TYPE_PACKAGE:
216 /* If method call or CopyObject - do not dereference */
218 if ((WalkState->Opcode == AML_INT_METHODCALL_OP) ||
219 (WalkState->Opcode == AML_COPY_OP))
224 /* Otherwise, dereference the PackageIndex to a package element */
226 ObjDesc = *StackDesc->Reference.Where;
230 * Valid object descriptor, copy pointer to return value
231 * (i.e., dereference the package index)
232 * Delete the ref object, increment the returned object
234 AcpiUtRemoveReference (StackDesc);
235 AcpiUtAddReference (ObjDesc);
241 * A NULL object descriptor means an uninitialized element of
242 * the package, can't dereference it
244 ACPI_ERROR ((AE_INFO,
245 "Attempt to dereference an Index to NULL package element Idx=%p",
247 Status = AE_AML_UNINITIALIZED_ELEMENT;
254 /* Invalid reference object */
256 ACPI_ERROR ((AE_INFO,
257 "Unknown TargetType 0x%X in Index/Reference object %p",
258 StackDesc->Reference.TargetType, StackDesc));
259 Status = AE_AML_INTERNAL;
265 case ACPI_REFCLASS_REFOF:
266 case ACPI_REFCLASS_DEBUG:
267 case ACPI_REFCLASS_TABLE:
269 /* Just leave the object as-is, do not dereference */
273 case ACPI_REFCLASS_NAME: /* Reference to a named object */
275 /* Dereference the name */
277 if ((StackDesc->Reference.Node->Type == ACPI_TYPE_DEVICE) ||
278 (StackDesc->Reference.Node->Type == ACPI_TYPE_THERMAL))
280 /* These node types do not have 'real' subobjects */
282 *StackPtr = (void *) StackDesc->Reference.Node;
286 /* Get the object pointed to by the namespace node */
288 *StackPtr = (StackDesc->Reference.Node)->Object;
289 AcpiUtAddReference (*StackPtr);
292 AcpiUtRemoveReference (StackDesc);
297 ACPI_ERROR ((AE_INFO,
298 "Unknown Reference type 0x%X in %p", RefType, StackDesc));
299 Status = AE_AML_INTERNAL;
305 case ACPI_TYPE_BUFFER:
307 Status = AcpiDsGetBufferArguments (StackDesc);
311 case ACPI_TYPE_PACKAGE:
313 Status = AcpiDsGetPackageArguments (StackDesc);
317 case ACPI_TYPE_BUFFER_FIELD:
318 case ACPI_TYPE_LOCAL_REGION_FIELD:
319 case ACPI_TYPE_LOCAL_BANK_FIELD:
320 case ACPI_TYPE_LOCAL_INDEX_FIELD:
322 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "FieldRead SourceDesc=%p Type=%X\n",
323 StackDesc, StackDesc->Common.Type));
325 Status = AcpiExReadDataFromField (WalkState, StackDesc, &ObjDesc);
327 /* Remove a reference to the original operand, then override */
329 AcpiUtRemoveReference (*StackPtr);
330 *StackPtr = (void *) ObjDesc;
337 return_ACPI_STATUS (Status);
341 /*******************************************************************************
343 * FUNCTION: AcpiExResolveMultiple
345 * PARAMETERS: WalkState - Current state (contains AML opcode)
346 * Operand - Starting point for resolution
347 * ReturnType - Where the object type is returned
348 * ReturnDesc - Where the resolved object is returned
352 * DESCRIPTION: Return the base object and type. Traverse a reference list if
353 * necessary to get to the base object.
355 ******************************************************************************/
358 AcpiExResolveMultiple (
359 ACPI_WALK_STATE *WalkState,
360 ACPI_OPERAND_OBJECT *Operand,
361 ACPI_OBJECT_TYPE *ReturnType,
362 ACPI_OPERAND_OBJECT **ReturnDesc)
364 ACPI_OPERAND_OBJECT *ObjDesc = (void *) Operand;
365 ACPI_NAMESPACE_NODE *Node;
366 ACPI_OBJECT_TYPE Type;
370 ACPI_FUNCTION_TRACE (AcpiExResolveMultiple);
373 /* Operand can be either a namespace node or an operand descriptor */
375 switch (ACPI_GET_DESCRIPTOR_TYPE (ObjDesc))
377 case ACPI_DESC_TYPE_OPERAND:
378 Type = ObjDesc->Common.Type;
381 case ACPI_DESC_TYPE_NAMED:
382 Type = ((ACPI_NAMESPACE_NODE *) ObjDesc)->Type;
383 ObjDesc = AcpiNsGetAttachedObject ((ACPI_NAMESPACE_NODE *) ObjDesc);
385 /* If we had an Alias node, use the attached object for type info */
387 if (Type == ACPI_TYPE_LOCAL_ALIAS)
389 Type = ((ACPI_NAMESPACE_NODE *) ObjDesc)->Type;
390 ObjDesc = AcpiNsGetAttachedObject ((ACPI_NAMESPACE_NODE *) ObjDesc);
395 return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
398 /* If type is anything other than a reference, we are done */
400 if (Type != ACPI_TYPE_LOCAL_REFERENCE)
406 * For reference objects created via the RefOf, Index, or Load/LoadTable
407 * operators, we need to get to the base object (as per the ACPI
408 * specification of the ObjectType and SizeOf operators). This means
409 * traversing the list of possibly many nested references.
411 while (ObjDesc->Common.Type == ACPI_TYPE_LOCAL_REFERENCE)
413 switch (ObjDesc->Reference.Class)
415 case ACPI_REFCLASS_REFOF:
416 case ACPI_REFCLASS_NAME:
418 /* Dereference the reference pointer */
420 if (ObjDesc->Reference.Class == ACPI_REFCLASS_REFOF)
422 Node = ObjDesc->Reference.Object;
424 else /* AML_INT_NAMEPATH_OP */
426 Node = ObjDesc->Reference.Node;
429 /* All "References" point to a NS node */
431 if (ACPI_GET_DESCRIPTOR_TYPE (Node) != ACPI_DESC_TYPE_NAMED)
433 ACPI_ERROR ((AE_INFO,
434 "Not a namespace node %p [%s]",
435 Node, AcpiUtGetDescriptorName (Node)));
436 return_ACPI_STATUS (AE_AML_INTERNAL);
439 /* Get the attached object */
441 ObjDesc = AcpiNsGetAttachedObject (Node);
444 /* No object, use the NS node type */
446 Type = AcpiNsGetType (Node);
450 /* Check for circular references */
452 if (ObjDesc == Operand)
454 return_ACPI_STATUS (AE_AML_CIRCULAR_REFERENCE);
459 case ACPI_REFCLASS_INDEX:
461 /* Get the type of this reference (index into another object) */
463 Type = ObjDesc->Reference.TargetType;
464 if (Type != ACPI_TYPE_PACKAGE)
470 * The main object is a package, we want to get the type
471 * of the individual package element that is referenced by
474 * This could of course in turn be another reference object.
476 ObjDesc = *(ObjDesc->Reference.Where);
479 /* NULL package elements are allowed */
481 Type = 0; /* Uninitialized */
487 case ACPI_REFCLASS_TABLE:
489 Type = ACPI_TYPE_DDB_HANDLE;
493 case ACPI_REFCLASS_LOCAL:
494 case ACPI_REFCLASS_ARG:
498 Status = AcpiDsMethodDataGetValue (ObjDesc->Reference.Class,
499 ObjDesc->Reference.Value, WalkState, &ObjDesc);
500 if (ACPI_FAILURE (Status))
502 return_ACPI_STATUS (Status);
504 AcpiUtRemoveReference (ObjDesc);
508 Status = AcpiDsMethodDataGetNode (ObjDesc->Reference.Class,
509 ObjDesc->Reference.Value, WalkState, &Node);
510 if (ACPI_FAILURE (Status))
512 return_ACPI_STATUS (Status);
515 ObjDesc = AcpiNsGetAttachedObject (Node);
518 Type = ACPI_TYPE_ANY;
525 case ACPI_REFCLASS_DEBUG:
527 /* The Debug Object is of type "DebugObject" */
529 Type = ACPI_TYPE_DEBUG_OBJECT;
535 ACPI_ERROR ((AE_INFO,
536 "Unknown Reference Class 0x%2.2X", ObjDesc->Reference.Class));
537 return_ACPI_STATUS (AE_AML_INTERNAL);
542 * Now we are guaranteed to have an object that has not been created
543 * via the RefOf or Index operators.
545 Type = ObjDesc->Common.Type;
549 /* Convert internal types to external types */
553 case ACPI_TYPE_LOCAL_REGION_FIELD:
554 case ACPI_TYPE_LOCAL_BANK_FIELD:
555 case ACPI_TYPE_LOCAL_INDEX_FIELD:
557 Type = ACPI_TYPE_FIELD_UNIT;
560 case ACPI_TYPE_LOCAL_SCOPE:
562 /* Per ACPI Specification, Scope is untyped */
564 Type = ACPI_TYPE_ANY;
568 /* No change to Type required */
575 *ReturnDesc = ObjDesc;
577 return_ACPI_STATUS (AE_OK);