1 /******************************************************************************
3 * Module Name: exresolv - AML Interpreter object resolution
5 *****************************************************************************/
8 * Copyright (C) 2000 - 2013, 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.
44 #define __EXRESOLV_C__
54 #define _COMPONENT ACPI_EXECUTER
55 ACPI_MODULE_NAME ("exresolv")
57 /* Local prototypes */
60 AcpiExResolveObjectToValue (
61 ACPI_OPERAND_OBJECT
**StackPtr
,
62 ACPI_WALK_STATE
*WalkState
);
65 /*******************************************************************************
67 * FUNCTION: AcpiExResolveToValue
69 * PARAMETERS: **StackPtr - Points to entry on ObjStack, which can
70 * be either an (ACPI_OPERAND_OBJECT *)
72 * WalkState - Current method state
76 * DESCRIPTION: Convert Reference objects to values
78 ******************************************************************************/
81 AcpiExResolveToValue (
82 ACPI_OPERAND_OBJECT
**StackPtr
,
83 ACPI_WALK_STATE
*WalkState
)
88 ACPI_FUNCTION_TRACE_PTR (ExResolveToValue
, StackPtr
);
91 if (!StackPtr
|| !*StackPtr
)
93 ACPI_ERROR ((AE_INFO
, "Internal - null pointer"));
94 return_ACPI_STATUS (AE_AML_NO_OPERAND
);
98 * The entity pointed to by the StackPtr can be either
99 * 1) A valid ACPI_OPERAND_OBJECT, or
100 * 2) A ACPI_NAMESPACE_NODE (NamedObj)
102 if (ACPI_GET_DESCRIPTOR_TYPE (*StackPtr
) == ACPI_DESC_TYPE_OPERAND
)
104 Status
= AcpiExResolveObjectToValue (StackPtr
, WalkState
);
105 if (ACPI_FAILURE (Status
))
107 return_ACPI_STATUS (Status
);
112 ACPI_ERROR ((AE_INFO
, "Internal - null pointer"));
113 return_ACPI_STATUS (AE_AML_NO_OPERAND
);
118 * Object on the stack may have changed if AcpiExResolveObjectToValue()
119 * was called (i.e., we can't use an _else_ here.)
121 if (ACPI_GET_DESCRIPTOR_TYPE (*StackPtr
) == ACPI_DESC_TYPE_NAMED
)
123 Status
= AcpiExResolveNodeToValue (
124 ACPI_CAST_INDIRECT_PTR (ACPI_NAMESPACE_NODE
, StackPtr
),
126 if (ACPI_FAILURE (Status
))
128 return_ACPI_STATUS (Status
);
132 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC
, "Resolved object %p\n", *StackPtr
));
133 return_ACPI_STATUS (AE_OK
);
137 /*******************************************************************************
139 * FUNCTION: AcpiExResolveObjectToValue
141 * PARAMETERS: StackPtr - Pointer to an internal object
142 * WalkState - Current method state
146 * DESCRIPTION: Retrieve the value from an internal object. The Reference type
147 * uses the associated AML opcode to determine the value.
149 ******************************************************************************/
152 AcpiExResolveObjectToValue (
153 ACPI_OPERAND_OBJECT
**StackPtr
,
154 ACPI_WALK_STATE
*WalkState
)
156 ACPI_STATUS Status
= AE_OK
;
157 ACPI_OPERAND_OBJECT
*StackDesc
;
158 ACPI_OPERAND_OBJECT
*ObjDesc
= NULL
;
162 ACPI_FUNCTION_TRACE (ExResolveObjectToValue
);
165 StackDesc
= *StackPtr
;
167 /* This is an object of type ACPI_OPERAND_OBJECT */
169 switch (StackDesc
->Common
.Type
)
171 case ACPI_TYPE_LOCAL_REFERENCE
:
173 RefType
= StackDesc
->Reference
.Class
;
177 case ACPI_REFCLASS_LOCAL
:
178 case ACPI_REFCLASS_ARG
:
180 * Get the local from the method's state info
181 * Note: this increments the local's object reference count
183 Status
= AcpiDsMethodDataGetValue (RefType
,
184 StackDesc
->Reference
.Value
, WalkState
, &ObjDesc
);
185 if (ACPI_FAILURE (Status
))
187 return_ACPI_STATUS (Status
);
190 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC
, "[Arg/Local %X] ValueObj is %p\n",
191 StackDesc
->Reference
.Value
, ObjDesc
));
194 * Now we can delete the original Reference Object and
195 * replace it with the resolved value
197 AcpiUtRemoveReference (StackDesc
);
201 case ACPI_REFCLASS_INDEX
:
203 switch (StackDesc
->Reference
.TargetType
)
205 case ACPI_TYPE_BUFFER_FIELD
:
207 /* Just return - do not dereference */
210 case ACPI_TYPE_PACKAGE
:
212 /* If method call or CopyObject - do not dereference */
214 if ((WalkState
->Opcode
== AML_INT_METHODCALL_OP
) ||
215 (WalkState
->Opcode
== AML_COPY_OP
))
220 /* Otherwise, dereference the PackageIndex to a package element */
222 ObjDesc
= *StackDesc
->Reference
.Where
;
226 * Valid object descriptor, copy pointer to return value
227 * (i.e., dereference the package index)
228 * Delete the ref object, increment the returned object
230 AcpiUtRemoveReference (StackDesc
);
231 AcpiUtAddReference (ObjDesc
);
237 * A NULL object descriptor means an uninitialized element of
238 * the package, can't dereference it
240 ACPI_ERROR ((AE_INFO
,
241 "Attempt to dereference an Index to NULL package element Idx=%p",
243 Status
= AE_AML_UNINITIALIZED_ELEMENT
;
249 /* Invalid reference object */
251 ACPI_ERROR ((AE_INFO
,
252 "Unknown TargetType 0x%X in Index/Reference object %p",
253 StackDesc
->Reference
.TargetType
, StackDesc
));
254 Status
= AE_AML_INTERNAL
;
259 case ACPI_REFCLASS_REFOF
:
260 case ACPI_REFCLASS_DEBUG
:
261 case ACPI_REFCLASS_TABLE
:
263 /* Just leave the object as-is, do not dereference */
267 case ACPI_REFCLASS_NAME
: /* Reference to a named object */
269 /* Dereference the name */
271 if ((StackDesc
->Reference
.Node
->Type
== ACPI_TYPE_DEVICE
) ||
272 (StackDesc
->Reference
.Node
->Type
== ACPI_TYPE_THERMAL
))
274 /* These node types do not have 'real' subobjects */
276 *StackPtr
= (void *) StackDesc
->Reference
.Node
;
280 /* Get the object pointed to by the namespace node */
282 *StackPtr
= (StackDesc
->Reference
.Node
)->Object
;
283 AcpiUtAddReference (*StackPtr
);
286 AcpiUtRemoveReference (StackDesc
);
291 ACPI_ERROR ((AE_INFO
,
292 "Unknown Reference type 0x%X in %p", RefType
, StackDesc
));
293 Status
= AE_AML_INTERNAL
;
298 case ACPI_TYPE_BUFFER
:
300 Status
= AcpiDsGetBufferArguments (StackDesc
);
303 case ACPI_TYPE_PACKAGE
:
305 Status
= AcpiDsGetPackageArguments (StackDesc
);
308 case ACPI_TYPE_BUFFER_FIELD
:
309 case ACPI_TYPE_LOCAL_REGION_FIELD
:
310 case ACPI_TYPE_LOCAL_BANK_FIELD
:
311 case ACPI_TYPE_LOCAL_INDEX_FIELD
:
313 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC
, "FieldRead SourceDesc=%p Type=%X\n",
314 StackDesc
, StackDesc
->Common
.Type
));
316 Status
= AcpiExReadDataFromField (WalkState
, StackDesc
, &ObjDesc
);
318 /* Remove a reference to the original operand, then override */
320 AcpiUtRemoveReference (*StackPtr
);
321 *StackPtr
= (void *) ObjDesc
;
329 return_ACPI_STATUS (Status
);
333 /*******************************************************************************
335 * FUNCTION: AcpiExResolveMultiple
337 * PARAMETERS: WalkState - Current state (contains AML opcode)
338 * Operand - Starting point for resolution
339 * ReturnType - Where the object type is returned
340 * ReturnDesc - Where the resolved object is returned
344 * DESCRIPTION: Return the base object and type. Traverse a reference list if
345 * necessary to get to the base object.
347 ******************************************************************************/
350 AcpiExResolveMultiple (
351 ACPI_WALK_STATE
*WalkState
,
352 ACPI_OPERAND_OBJECT
*Operand
,
353 ACPI_OBJECT_TYPE
*ReturnType
,
354 ACPI_OPERAND_OBJECT
**ReturnDesc
)
356 ACPI_OPERAND_OBJECT
*ObjDesc
= (void *) Operand
;
357 ACPI_NAMESPACE_NODE
*Node
;
358 ACPI_OBJECT_TYPE Type
;
362 ACPI_FUNCTION_TRACE (AcpiExResolveMultiple
);
365 /* Operand can be either a namespace node or an operand descriptor */
367 switch (ACPI_GET_DESCRIPTOR_TYPE (ObjDesc
))
369 case ACPI_DESC_TYPE_OPERAND
:
371 Type
= ObjDesc
->Common
.Type
;
374 case ACPI_DESC_TYPE_NAMED
:
376 Type
= ((ACPI_NAMESPACE_NODE
*) ObjDesc
)->Type
;
377 ObjDesc
= AcpiNsGetAttachedObject ((ACPI_NAMESPACE_NODE
*) ObjDesc
);
379 /* If we had an Alias node, use the attached object for type info */
381 if (Type
== ACPI_TYPE_LOCAL_ALIAS
)
383 Type
= ((ACPI_NAMESPACE_NODE
*) ObjDesc
)->Type
;
384 ObjDesc
= AcpiNsGetAttachedObject ((ACPI_NAMESPACE_NODE
*) ObjDesc
);
389 return_ACPI_STATUS (AE_AML_OPERAND_TYPE
);
392 /* If type is anything other than a reference, we are done */
394 if (Type
!= ACPI_TYPE_LOCAL_REFERENCE
)
400 * For reference objects created via the RefOf, Index, or Load/LoadTable
401 * operators, we need to get to the base object (as per the ACPI
402 * specification of the ObjectType and SizeOf operators). This means
403 * traversing the list of possibly many nested references.
405 while (ObjDesc
->Common
.Type
== ACPI_TYPE_LOCAL_REFERENCE
)
407 switch (ObjDesc
->Reference
.Class
)
409 case ACPI_REFCLASS_REFOF
:
410 case ACPI_REFCLASS_NAME
:
412 /* Dereference the reference pointer */
414 if (ObjDesc
->Reference
.Class
== ACPI_REFCLASS_REFOF
)
416 Node
= ObjDesc
->Reference
.Object
;
418 else /* AML_INT_NAMEPATH_OP */
420 Node
= ObjDesc
->Reference
.Node
;
423 /* All "References" point to a NS node */
425 if (ACPI_GET_DESCRIPTOR_TYPE (Node
) != ACPI_DESC_TYPE_NAMED
)
427 ACPI_ERROR ((AE_INFO
,
428 "Not a namespace node %p [%s]",
429 Node
, AcpiUtGetDescriptorName (Node
)));
430 return_ACPI_STATUS (AE_AML_INTERNAL
);
433 /* Get the attached object */
435 ObjDesc
= AcpiNsGetAttachedObject (Node
);
438 /* No object, use the NS node type */
440 Type
= AcpiNsGetType (Node
);
444 /* Check for circular references */
446 if (ObjDesc
== Operand
)
448 return_ACPI_STATUS (AE_AML_CIRCULAR_REFERENCE
);
452 case ACPI_REFCLASS_INDEX
:
454 /* Get the type of this reference (index into another object) */
456 Type
= ObjDesc
->Reference
.TargetType
;
457 if (Type
!= ACPI_TYPE_PACKAGE
)
463 * The main object is a package, we want to get the type
464 * of the individual package element that is referenced by
467 * This could of course in turn be another reference object.
469 ObjDesc
= *(ObjDesc
->Reference
.Where
);
472 /* NULL package elements are allowed */
474 Type
= 0; /* Uninitialized */
479 case ACPI_REFCLASS_TABLE
:
481 Type
= ACPI_TYPE_DDB_HANDLE
;
484 case ACPI_REFCLASS_LOCAL
:
485 case ACPI_REFCLASS_ARG
:
489 Status
= AcpiDsMethodDataGetValue (ObjDesc
->Reference
.Class
,
490 ObjDesc
->Reference
.Value
, WalkState
, &ObjDesc
);
491 if (ACPI_FAILURE (Status
))
493 return_ACPI_STATUS (Status
);
495 AcpiUtRemoveReference (ObjDesc
);
499 Status
= AcpiDsMethodDataGetNode (ObjDesc
->Reference
.Class
,
500 ObjDesc
->Reference
.Value
, WalkState
, &Node
);
501 if (ACPI_FAILURE (Status
))
503 return_ACPI_STATUS (Status
);
506 ObjDesc
= AcpiNsGetAttachedObject (Node
);
509 Type
= ACPI_TYPE_ANY
;
515 case ACPI_REFCLASS_DEBUG
:
517 /* The Debug Object is of type "DebugObject" */
519 Type
= ACPI_TYPE_DEBUG_OBJECT
;
524 ACPI_ERROR ((AE_INFO
,
525 "Unknown Reference Class 0x%2.2X", ObjDesc
->Reference
.Class
));
526 return_ACPI_STATUS (AE_AML_INTERNAL
);
531 * Now we are guaranteed to have an object that has not been created
532 * via the RefOf or Index operators.
534 Type
= ObjDesc
->Common
.Type
;
538 /* Convert internal types to external types */
542 case ACPI_TYPE_LOCAL_REGION_FIELD
:
543 case ACPI_TYPE_LOCAL_BANK_FIELD
:
544 case ACPI_TYPE_LOCAL_INDEX_FIELD
:
546 Type
= ACPI_TYPE_FIELD_UNIT
;
549 case ACPI_TYPE_LOCAL_SCOPE
:
551 /* Per ACPI Specification, Scope is untyped */
553 Type
= ACPI_TYPE_ANY
;
558 /* No change to Type required */
566 *ReturnDesc
= ObjDesc
;
568 return_ACPI_STATUS (AE_OK
);