Fixed compatibility of output.
[AROS.git] / arch / all-pc / acpica / source / components / executer / exresolv.c
blobe99d46c5b5b0ad7f325cadca9478cea9e0770723
1 /******************************************************************************
3 * Module Name: exresolv - AML Interpreter object resolution
5 *****************************************************************************/
7 /*
8 * Copyright (C) 2000 - 2013, Intel Corp.
9 * All rights reserved.
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
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.
30 * NO WARRANTY
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__
46 #include "acpi.h"
47 #include "accommon.h"
48 #include "amlcode.h"
49 #include "acdispat.h"
50 #include "acinterp.h"
51 #include "acnamesp.h"
54 #define _COMPONENT ACPI_EXECUTER
55 ACPI_MODULE_NAME ("exresolv")
57 /* Local prototypes */
59 static ACPI_STATUS
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 *)
71 * or an ACPI_HANDLE.
72 * WalkState - Current method state
74 * RETURN: Status
76 * DESCRIPTION: Convert Reference objects to values
78 ******************************************************************************/
80 ACPI_STATUS
81 AcpiExResolveToValue (
82 ACPI_OPERAND_OBJECT **StackPtr,
83 ACPI_WALK_STATE *WalkState)
85 ACPI_STATUS Status;
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);
110 if (!*StackPtr)
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),
125 WalkState);
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
144 * RETURN: Status
146 * DESCRIPTION: Retrieve the value from an internal object. The Reference type
147 * uses the associated AML opcode to determine the value.
149 ******************************************************************************/
151 static ACPI_STATUS
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;
159 UINT8 RefType;
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;
175 switch (RefType)
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);
198 *StackPtr = ObjDesc;
199 break;
201 case ACPI_REFCLASS_INDEX:
203 switch (StackDesc->Reference.TargetType)
205 case ACPI_TYPE_BUFFER_FIELD:
207 /* Just return - do not dereference */
208 break;
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))
217 break;
220 /* Otherwise, dereference the PackageIndex to a package element */
222 ObjDesc = *StackDesc->Reference.Where;
223 if (ObjDesc)
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);
232 *StackPtr = ObjDesc;
234 else
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",
242 StackDesc));
243 Status = AE_AML_UNINITIALIZED_ELEMENT;
245 break;
247 default:
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;
255 break;
257 break;
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 */
265 break;
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;
278 else
280 /* Get the object pointed to by the namespace node */
282 *StackPtr = (StackDesc->Reference.Node)->Object;
283 AcpiUtAddReference (*StackPtr);
286 AcpiUtRemoveReference (StackDesc);
287 break;
289 default:
291 ACPI_ERROR ((AE_INFO,
292 "Unknown Reference type 0x%X in %p", RefType, StackDesc));
293 Status = AE_AML_INTERNAL;
294 break;
296 break;
298 case ACPI_TYPE_BUFFER:
300 Status = AcpiDsGetBufferArguments (StackDesc);
301 break;
303 case ACPI_TYPE_PACKAGE:
305 Status = AcpiDsGetPackageArguments (StackDesc);
306 break;
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;
322 break;
324 default:
326 break;
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
342 * RETURN: Status
344 * DESCRIPTION: Return the base object and type. Traverse a reference list if
345 * necessary to get to the base object.
347 ******************************************************************************/
349 ACPI_STATUS
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;
359 ACPI_STATUS Status;
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;
372 break;
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);
386 break;
388 default:
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)
396 goto Exit;
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);
436 if (!ObjDesc)
438 /* No object, use the NS node type */
440 Type = AcpiNsGetType (Node);
441 goto Exit;
444 /* Check for circular references */
446 if (ObjDesc == Operand)
448 return_ACPI_STATUS (AE_AML_CIRCULAR_REFERENCE);
450 break;
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)
459 goto Exit;
463 * The main object is a package, we want to get the type
464 * of the individual package element that is referenced by
465 * the index.
467 * This could of course in turn be another reference object.
469 ObjDesc = *(ObjDesc->Reference.Where);
470 if (!ObjDesc)
472 /* NULL package elements are allowed */
474 Type = 0; /* Uninitialized */
475 goto Exit;
477 break;
479 case ACPI_REFCLASS_TABLE:
481 Type = ACPI_TYPE_DDB_HANDLE;
482 goto Exit;
484 case ACPI_REFCLASS_LOCAL:
485 case ACPI_REFCLASS_ARG:
487 if (ReturnDesc)
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);
497 else
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);
507 if (!ObjDesc)
509 Type = ACPI_TYPE_ANY;
510 goto Exit;
513 break;
515 case ACPI_REFCLASS_DEBUG:
517 /* The Debug Object is of type "DebugObject" */
519 Type = ACPI_TYPE_DEBUG_OBJECT;
520 goto Exit;
522 default:
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;
537 Exit:
538 /* Convert internal types to external types */
540 switch (Type)
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;
547 break;
549 case ACPI_TYPE_LOCAL_SCOPE:
551 /* Per ACPI Specification, Scope is untyped */
553 Type = ACPI_TYPE_ANY;
554 break;
556 default:
558 /* No change to Type required */
560 break;
563 *ReturnType = Type;
564 if (ReturnDesc)
566 *ReturnDesc = ObjDesc;
568 return_ACPI_STATUS (AE_OK);