1 /******************************************************************************
3 * Module Name: exresolv - AML Interpreter object resolution
5 *****************************************************************************/
8 * Copyright (C) 2000 - 2016, 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.
52 #define _COMPONENT ACPI_EXECUTER
53 ACPI_MODULE_NAME ("exresolv")
55 /* Local prototypes */
58 AcpiExResolveObjectToValue (
59 ACPI_OPERAND_OBJECT
**StackPtr
,
60 ACPI_WALK_STATE
*WalkState
);
63 /*******************************************************************************
65 * FUNCTION: AcpiExResolveToValue
67 * PARAMETERS: **StackPtr - Points to entry on ObjStack, which can
68 * be either an (ACPI_OPERAND_OBJECT *)
70 * WalkState - Current method state
74 * DESCRIPTION: Convert Reference objects to values
76 ******************************************************************************/
79 AcpiExResolveToValue (
80 ACPI_OPERAND_OBJECT
**StackPtr
,
81 ACPI_WALK_STATE
*WalkState
)
86 ACPI_FUNCTION_TRACE_PTR (ExResolveToValue
, StackPtr
);
89 if (!StackPtr
|| !*StackPtr
)
91 ACPI_ERROR ((AE_INFO
, "Internal - null pointer"));
92 return_ACPI_STATUS (AE_AML_NO_OPERAND
);
96 * The entity pointed to by the StackPtr can be either
97 * 1) A valid ACPI_OPERAND_OBJECT, or
98 * 2) A ACPI_NAMESPACE_NODE (NamedObj)
100 if (ACPI_GET_DESCRIPTOR_TYPE (*StackPtr
) == ACPI_DESC_TYPE_OPERAND
)
102 Status
= AcpiExResolveObjectToValue (StackPtr
, WalkState
);
103 if (ACPI_FAILURE (Status
))
105 return_ACPI_STATUS (Status
);
110 ACPI_ERROR ((AE_INFO
, "Internal - null pointer"));
111 return_ACPI_STATUS (AE_AML_NO_OPERAND
);
116 * Object on the stack may have changed if AcpiExResolveObjectToValue()
117 * was called (i.e., we can't use an _else_ here.)
119 if (ACPI_GET_DESCRIPTOR_TYPE (*StackPtr
) == ACPI_DESC_TYPE_NAMED
)
121 Status
= AcpiExResolveNodeToValue (
122 ACPI_CAST_INDIRECT_PTR (ACPI_NAMESPACE_NODE
, StackPtr
),
124 if (ACPI_FAILURE (Status
))
126 return_ACPI_STATUS (Status
);
130 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC
, "Resolved object %p\n", *StackPtr
));
131 return_ACPI_STATUS (AE_OK
);
135 /*******************************************************************************
137 * FUNCTION: AcpiExResolveObjectToValue
139 * PARAMETERS: StackPtr - Pointer to an internal object
140 * WalkState - Current method state
144 * DESCRIPTION: Retrieve the value from an internal object. The Reference type
145 * uses the associated AML opcode to determine the value.
147 ******************************************************************************/
150 AcpiExResolveObjectToValue (
151 ACPI_OPERAND_OBJECT
**StackPtr
,
152 ACPI_WALK_STATE
*WalkState
)
154 ACPI_STATUS Status
= AE_OK
;
155 ACPI_OPERAND_OBJECT
*StackDesc
;
156 ACPI_OPERAND_OBJECT
*ObjDesc
= NULL
;
160 ACPI_FUNCTION_TRACE (ExResolveObjectToValue
);
163 StackDesc
= *StackPtr
;
165 /* This is an object of type ACPI_OPERAND_OBJECT */
167 switch (StackDesc
->Common
.Type
)
169 case ACPI_TYPE_LOCAL_REFERENCE
:
171 RefType
= StackDesc
->Reference
.Class
;
175 case ACPI_REFCLASS_LOCAL
:
176 case ACPI_REFCLASS_ARG
:
178 * Get the local from the method's state info
179 * Note: this increments the local's object reference count
181 Status
= AcpiDsMethodDataGetValue (RefType
,
182 StackDesc
->Reference
.Value
, WalkState
, &ObjDesc
);
183 if (ACPI_FAILURE (Status
))
185 return_ACPI_STATUS (Status
);
188 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC
, "[Arg/Local %X] ValueObj is %p\n",
189 StackDesc
->Reference
.Value
, ObjDesc
));
192 * Now we can delete the original Reference Object and
193 * replace it with the resolved value
195 AcpiUtRemoveReference (StackDesc
);
199 case ACPI_REFCLASS_INDEX
:
201 switch (StackDesc
->Reference
.TargetType
)
203 case ACPI_TYPE_BUFFER_FIELD
:
205 /* Just return - do not dereference */
208 case ACPI_TYPE_PACKAGE
:
210 /* If method call or CopyObject - do not dereference */
212 if ((WalkState
->Opcode
== AML_INT_METHODCALL_OP
) ||
213 (WalkState
->Opcode
== AML_COPY_OP
))
218 /* Otherwise, dereference the PackageIndex to a package element */
220 ObjDesc
= *StackDesc
->Reference
.Where
;
224 * Valid object descriptor, copy pointer to return value
225 * (i.e., dereference the package index)
226 * Delete the ref object, increment the returned object
228 AcpiUtAddReference (ObjDesc
);
234 * A NULL object descriptor means an uninitialized element of
235 * the package, can't dereference it
237 ACPI_ERROR ((AE_INFO
,
238 "Attempt to dereference an Index to "
239 "NULL package element Idx=%p",
241 Status
= AE_AML_UNINITIALIZED_ELEMENT
;
247 /* Invalid reference object */
249 ACPI_ERROR ((AE_INFO
,
250 "Unknown TargetType 0x%X in Index/Reference object %p",
251 StackDesc
->Reference
.TargetType
, StackDesc
));
252 Status
= AE_AML_INTERNAL
;
257 case ACPI_REFCLASS_REFOF
:
258 case ACPI_REFCLASS_DEBUG
:
259 case ACPI_REFCLASS_TABLE
:
261 /* Just leave the object as-is, do not dereference */
265 case ACPI_REFCLASS_NAME
: /* Reference to a named object */
267 /* Dereference the name */
269 if ((StackDesc
->Reference
.Node
->Type
== ACPI_TYPE_DEVICE
) ||
270 (StackDesc
->Reference
.Node
->Type
== ACPI_TYPE_THERMAL
))
272 /* These node types do not have 'real' subobjects */
274 *StackPtr
= (void *) StackDesc
->Reference
.Node
;
278 /* Get the object pointed to by the namespace node */
280 *StackPtr
= (StackDesc
->Reference
.Node
)->Object
;
281 AcpiUtAddReference (*StackPtr
);
284 AcpiUtRemoveReference (StackDesc
);
289 ACPI_ERROR ((AE_INFO
,
290 "Unknown Reference type 0x%X in %p",
291 RefType
, StackDesc
));
292 Status
= AE_AML_INTERNAL
;
297 case ACPI_TYPE_BUFFER
:
299 Status
= AcpiDsGetBufferArguments (StackDesc
);
302 case ACPI_TYPE_PACKAGE
:
304 Status
= AcpiDsGetPackageArguments (StackDesc
);
307 case ACPI_TYPE_BUFFER_FIELD
:
308 case ACPI_TYPE_LOCAL_REGION_FIELD
:
309 case ACPI_TYPE_LOCAL_BANK_FIELD
:
310 case ACPI_TYPE_LOCAL_INDEX_FIELD
:
312 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC
,
313 "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
= ACPI_CAST_PTR (void, Operand
);
357 ACPI_NAMESPACE_NODE
*Node
= ACPI_CAST_PTR (ACPI_NAMESPACE_NODE
, Operand
);
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 (Node
);
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 (
385 (ACPI_NAMESPACE_NODE
*) ObjDesc
);
390 ACPI_ERROR ((AE_INFO
,
391 "[%4.4s] Node is unresolved or uninitialized",
392 AcpiUtGetNodeName (Node
)));
393 return_ACPI_STATUS (AE_AML_UNINITIALIZED_NODE
);
398 return_ACPI_STATUS (AE_AML_OPERAND_TYPE
);
401 /* If type is anything other than a reference, we are done */
403 if (Type
!= ACPI_TYPE_LOCAL_REFERENCE
)
409 * For reference objects created via the RefOf, Index, or Load/LoadTable
410 * operators, we need to get to the base object (as per the ACPI
411 * specification of the ObjectType and SizeOf operators). This means
412 * traversing the list of possibly many nested references.
414 while (ObjDesc
->Common
.Type
== ACPI_TYPE_LOCAL_REFERENCE
)
416 switch (ObjDesc
->Reference
.Class
)
418 case ACPI_REFCLASS_REFOF
:
419 case ACPI_REFCLASS_NAME
:
421 /* Dereference the reference pointer */
423 if (ObjDesc
->Reference
.Class
== ACPI_REFCLASS_REFOF
)
425 Node
= ObjDesc
->Reference
.Object
;
427 else /* AML_INT_NAMEPATH_OP */
429 Node
= ObjDesc
->Reference
.Node
;
432 /* All "References" point to a NS node */
434 if (ACPI_GET_DESCRIPTOR_TYPE (Node
) != ACPI_DESC_TYPE_NAMED
)
436 ACPI_ERROR ((AE_INFO
,
437 "Not a namespace node %p [%s]",
438 Node
, AcpiUtGetDescriptorName (Node
)));
439 return_ACPI_STATUS (AE_AML_INTERNAL
);
442 /* Get the attached object */
444 ObjDesc
= AcpiNsGetAttachedObject (Node
);
447 /* No object, use the NS node type */
449 Type
= AcpiNsGetType (Node
);
453 /* Check for circular references */
455 if (ObjDesc
== Operand
)
457 return_ACPI_STATUS (AE_AML_CIRCULAR_REFERENCE
);
461 case ACPI_REFCLASS_INDEX
:
463 /* Get the type of this reference (index into another object) */
465 Type
= ObjDesc
->Reference
.TargetType
;
466 if (Type
!= ACPI_TYPE_PACKAGE
)
472 * The main object is a package, we want to get the type
473 * of the individual package element that is referenced by
476 * This could of course in turn be another reference object.
478 ObjDesc
= *(ObjDesc
->Reference
.Where
);
481 /* NULL package elements are allowed */
483 Type
= 0; /* Uninitialized */
488 case ACPI_REFCLASS_TABLE
:
490 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
;
524 case ACPI_REFCLASS_DEBUG
:
526 /* The Debug Object is of type "DebugObject" */
528 Type
= ACPI_TYPE_DEBUG_OBJECT
;
533 ACPI_ERROR ((AE_INFO
,
534 "Unknown Reference Class 0x%2.2X",
535 ObjDesc
->Reference
.Class
));
536 return_ACPI_STATUS (AE_AML_INTERNAL
);
541 * Now we are guaranteed to have an object that has not been created
542 * via the RefOf or Index operators.
544 Type
= ObjDesc
->Common
.Type
;
548 /* Convert internal types to external types */
552 case ACPI_TYPE_LOCAL_REGION_FIELD
:
553 case ACPI_TYPE_LOCAL_BANK_FIELD
:
554 case ACPI_TYPE_LOCAL_INDEX_FIELD
:
556 Type
= ACPI_TYPE_FIELD_UNIT
;
559 case ACPI_TYPE_LOCAL_SCOPE
:
561 /* Per ACPI Specification, Scope is untyped */
563 Type
= ACPI_TYPE_ANY
;
568 /* No change to Type required */
576 *ReturnDesc
= ObjDesc
;
578 return_ACPI_STATUS (AE_OK
);