1 /******************************************************************************
3 * Module Name: exresolv - AML Interpreter object resolution
5 *****************************************************************************/
8 * Copyright (C) 2000 - 2015, 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 AcpiUtRemoveReference (StackDesc);
229 AcpiUtAddReference (ObjDesc);
235 * A NULL object descriptor means an uninitialized element of
236 * the package, can't dereference it
238 ACPI_ERROR ((AE_INFO,
239 "Attempt to dereference an Index to 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", RefType, StackDesc));
291 Status = AE_AML_INTERNAL;
296 case ACPI_TYPE_BUFFER:
298 Status = AcpiDsGetBufferArguments (StackDesc);
301 case ACPI_TYPE_PACKAGE:
303 Status = AcpiDsGetPackageArguments (StackDesc);
306 case ACPI_TYPE_BUFFER_FIELD:
307 case ACPI_TYPE_LOCAL_REGION_FIELD:
308 case ACPI_TYPE_LOCAL_BANK_FIELD:
309 case ACPI_TYPE_LOCAL_INDEX_FIELD:
311 ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "FieldRead SourceDesc=%p Type=%X\n",
312 StackDesc, StackDesc->Common.Type));
314 Status = AcpiExReadDataFromField (WalkState, StackDesc, &ObjDesc);
316 /* Remove a reference to the original operand, then override */
318 AcpiUtRemoveReference (*StackPtr);
319 *StackPtr = (void *) ObjDesc;
327 return_ACPI_STATUS (Status);
331 /*******************************************************************************
333 * FUNCTION: AcpiExResolveMultiple
335 * PARAMETERS: WalkState - Current state (contains AML opcode)
336 * Operand - Starting point for resolution
337 * ReturnType - Where the object type is returned
338 * ReturnDesc - Where the resolved object is returned
342 * DESCRIPTION: Return the base object and type. Traverse a reference list if
343 * necessary to get to the base object.
345 ******************************************************************************/
348 AcpiExResolveMultiple (
349 ACPI_WALK_STATE *WalkState,
350 ACPI_OPERAND_OBJECT *Operand,
351 ACPI_OBJECT_TYPE *ReturnType,
352 ACPI_OPERAND_OBJECT **ReturnDesc)
354 ACPI_OPERAND_OBJECT *ObjDesc = (void *) Operand;
355 ACPI_NAMESPACE_NODE *Node;
356 ACPI_OBJECT_TYPE Type;
360 ACPI_FUNCTION_TRACE (AcpiExResolveMultiple);
363 /* Operand can be either a namespace node or an operand descriptor */
365 switch (ACPI_GET_DESCRIPTOR_TYPE (ObjDesc))
367 case ACPI_DESC_TYPE_OPERAND:
369 Type = ObjDesc->Common.Type;
372 case ACPI_DESC_TYPE_NAMED:
374 Type = ((ACPI_NAMESPACE_NODE *) ObjDesc)->Type;
375 ObjDesc = AcpiNsGetAttachedObject ((ACPI_NAMESPACE_NODE *) ObjDesc);
377 /* If we had an Alias node, use the attached object for type info */
379 if (Type == ACPI_TYPE_LOCAL_ALIAS)
381 Type = ((ACPI_NAMESPACE_NODE *) ObjDesc)->Type;
382 ObjDesc = AcpiNsGetAttachedObject ((ACPI_NAMESPACE_NODE *) ObjDesc);
387 return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
390 /* If type is anything other than a reference, we are done */
392 if (Type != ACPI_TYPE_LOCAL_REFERENCE)
398 * For reference objects created via the RefOf, Index, or Load/LoadTable
399 * operators, we need to get to the base object (as per the ACPI
400 * specification of the ObjectType and SizeOf operators). This means
401 * traversing the list of possibly many nested references.
403 while (ObjDesc->Common.Type == ACPI_TYPE_LOCAL_REFERENCE)
405 switch (ObjDesc->Reference.Class)
407 case ACPI_REFCLASS_REFOF:
408 case ACPI_REFCLASS_NAME:
410 /* Dereference the reference pointer */
412 if (ObjDesc->Reference.Class == ACPI_REFCLASS_REFOF)
414 Node = ObjDesc->Reference.Object;
416 else /* AML_INT_NAMEPATH_OP */
418 Node = ObjDesc->Reference.Node;
421 /* All "References" point to a NS node */
423 if (ACPI_GET_DESCRIPTOR_TYPE (Node) != ACPI_DESC_TYPE_NAMED)
425 ACPI_ERROR ((AE_INFO,
426 "Not a namespace node %p [%s]",
427 Node, AcpiUtGetDescriptorName (Node)));
428 return_ACPI_STATUS (AE_AML_INTERNAL);
431 /* Get the attached object */
433 ObjDesc = AcpiNsGetAttachedObject (Node);
436 /* No object, use the NS node type */
438 Type = AcpiNsGetType (Node);
442 /* Check for circular references */
444 if (ObjDesc == Operand)
446 return_ACPI_STATUS (AE_AML_CIRCULAR_REFERENCE);
450 case ACPI_REFCLASS_INDEX:
452 /* Get the type of this reference (index into another object) */
454 Type = ObjDesc->Reference.TargetType;
455 if (Type != ACPI_TYPE_PACKAGE)
461 * The main object is a package, we want to get the type
462 * of the individual package element that is referenced by
465 * This could of course in turn be another reference object.
467 ObjDesc = *(ObjDesc->Reference.Where);
470 /* NULL package elements are allowed */
472 Type = 0; /* Uninitialized */
477 case ACPI_REFCLASS_TABLE:
479 Type = ACPI_TYPE_DDB_HANDLE;
482 case ACPI_REFCLASS_LOCAL:
483 case ACPI_REFCLASS_ARG:
487 Status = AcpiDsMethodDataGetValue (ObjDesc->Reference.Class,
488 ObjDesc->Reference.Value, WalkState, &ObjDesc);
489 if (ACPI_FAILURE (Status))
491 return_ACPI_STATUS (Status);
493 AcpiUtRemoveReference (ObjDesc);
497 Status = AcpiDsMethodDataGetNode (ObjDesc->Reference.Class,
498 ObjDesc->Reference.Value, WalkState, &Node);
499 if (ACPI_FAILURE (Status))
501 return_ACPI_STATUS (Status);
504 ObjDesc = AcpiNsGetAttachedObject (Node);
507 Type = ACPI_TYPE_ANY;
513 case ACPI_REFCLASS_DEBUG:
515 /* The Debug Object is of type "DebugObject" */
517 Type = ACPI_TYPE_DEBUG_OBJECT;
522 ACPI_ERROR ((AE_INFO,
523 "Unknown Reference Class 0x%2.2X", ObjDesc->Reference.Class));
524 return_ACPI_STATUS (AE_AML_INTERNAL);
529 * Now we are guaranteed to have an object that has not been created
530 * via the RefOf or Index operators.
532 Type = ObjDesc->Common.Type;
536 /* Convert internal types to external types */
540 case ACPI_TYPE_LOCAL_REGION_FIELD:
541 case ACPI_TYPE_LOCAL_BANK_FIELD:
542 case ACPI_TYPE_LOCAL_INDEX_FIELD:
544 Type = ACPI_TYPE_FIELD_UNIT;
547 case ACPI_TYPE_LOCAL_SCOPE:
549 /* Per ACPI Specification, Scope is untyped */
551 Type = ACPI_TYPE_ANY;
556 /* No change to Type required */
564 *ReturnDesc = ObjDesc;
566 return_ACPI_STATUS (AE_OK);