1433d6423SLionel Sambuc /******************************************************************************
2433d6423SLionel Sambuc *
3433d6423SLionel Sambuc * Module Name: exresolv - AML Interpreter object resolution
4433d6423SLionel Sambuc *
5433d6423SLionel Sambuc *****************************************************************************/
6433d6423SLionel Sambuc
7*29492bb7SDavid van Moolenbroek /*
8*29492bb7SDavid van Moolenbroek * Copyright (C) 2000 - 2014, Intel Corp.
9433d6423SLionel Sambuc * All rights reserved.
10433d6423SLionel Sambuc *
11*29492bb7SDavid van Moolenbroek * Redistribution and use in source and binary forms, with or without
12*29492bb7SDavid van Moolenbroek * modification, are permitted provided that the following conditions
13*29492bb7SDavid van Moolenbroek * are met:
14*29492bb7SDavid van Moolenbroek * 1. Redistributions of source code must retain the above copyright
15*29492bb7SDavid van Moolenbroek * notice, this list of conditions, and the following disclaimer,
16*29492bb7SDavid van Moolenbroek * without modification.
17*29492bb7SDavid van Moolenbroek * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18*29492bb7SDavid van Moolenbroek * substantially similar to the "NO WARRANTY" disclaimer below
19*29492bb7SDavid van Moolenbroek * ("Disclaimer") and any redistribution must be conditioned upon
20*29492bb7SDavid van Moolenbroek * including a substantially similar Disclaimer requirement for further
21*29492bb7SDavid van Moolenbroek * binary redistribution.
22*29492bb7SDavid van Moolenbroek * 3. Neither the names of the above-listed copyright holders nor the names
23*29492bb7SDavid van Moolenbroek * of any contributors may be used to endorse or promote products derived
24*29492bb7SDavid van Moolenbroek * from this software without specific prior written permission.
25433d6423SLionel Sambuc *
26*29492bb7SDavid van Moolenbroek * Alternatively, this software may be distributed under the terms of the
27*29492bb7SDavid van Moolenbroek * GNU General Public License ("GPL") version 2 as published by the Free
28*29492bb7SDavid van Moolenbroek * Software Foundation.
29433d6423SLionel Sambuc *
30*29492bb7SDavid van Moolenbroek * NO WARRANTY
31*29492bb7SDavid van Moolenbroek * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32*29492bb7SDavid van Moolenbroek * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33*29492bb7SDavid van Moolenbroek * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34*29492bb7SDavid van Moolenbroek * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35*29492bb7SDavid van Moolenbroek * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36*29492bb7SDavid van Moolenbroek * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37*29492bb7SDavid van Moolenbroek * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38*29492bb7SDavid van Moolenbroek * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39*29492bb7SDavid van Moolenbroek * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40*29492bb7SDavid van Moolenbroek * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41*29492bb7SDavid van Moolenbroek * POSSIBILITY OF SUCH DAMAGES.
42*29492bb7SDavid van Moolenbroek */
43433d6423SLionel Sambuc
44433d6423SLionel Sambuc #include "acpi.h"
45433d6423SLionel Sambuc #include "accommon.h"
46433d6423SLionel Sambuc #include "amlcode.h"
47433d6423SLionel Sambuc #include "acdispat.h"
48433d6423SLionel Sambuc #include "acinterp.h"
49433d6423SLionel Sambuc #include "acnamesp.h"
50433d6423SLionel Sambuc
51433d6423SLionel Sambuc
52433d6423SLionel Sambuc #define _COMPONENT ACPI_EXECUTER
53433d6423SLionel Sambuc ACPI_MODULE_NAME ("exresolv")
54433d6423SLionel Sambuc
55433d6423SLionel Sambuc /* Local prototypes */
56433d6423SLionel Sambuc
57433d6423SLionel Sambuc static ACPI_STATUS
58433d6423SLionel Sambuc AcpiExResolveObjectToValue (
59433d6423SLionel Sambuc ACPI_OPERAND_OBJECT **StackPtr,
60433d6423SLionel Sambuc ACPI_WALK_STATE *WalkState);
61433d6423SLionel Sambuc
62433d6423SLionel Sambuc
63433d6423SLionel Sambuc /*******************************************************************************
64433d6423SLionel Sambuc *
65433d6423SLionel Sambuc * FUNCTION: AcpiExResolveToValue
66433d6423SLionel Sambuc *
67433d6423SLionel Sambuc * PARAMETERS: **StackPtr - Points to entry on ObjStack, which can
68433d6423SLionel Sambuc * be either an (ACPI_OPERAND_OBJECT *)
69433d6423SLionel Sambuc * or an ACPI_HANDLE.
70433d6423SLionel Sambuc * WalkState - Current method state
71433d6423SLionel Sambuc *
72433d6423SLionel Sambuc * RETURN: Status
73433d6423SLionel Sambuc *
74433d6423SLionel Sambuc * DESCRIPTION: Convert Reference objects to values
75433d6423SLionel Sambuc *
76433d6423SLionel Sambuc ******************************************************************************/
77433d6423SLionel Sambuc
78433d6423SLionel Sambuc ACPI_STATUS
AcpiExResolveToValue(ACPI_OPERAND_OBJECT ** StackPtr,ACPI_WALK_STATE * WalkState)79433d6423SLionel Sambuc AcpiExResolveToValue (
80433d6423SLionel Sambuc ACPI_OPERAND_OBJECT **StackPtr,
81433d6423SLionel Sambuc ACPI_WALK_STATE *WalkState)
82433d6423SLionel Sambuc {
83433d6423SLionel Sambuc ACPI_STATUS Status;
84433d6423SLionel Sambuc
85433d6423SLionel Sambuc
86433d6423SLionel Sambuc ACPI_FUNCTION_TRACE_PTR (ExResolveToValue, StackPtr);
87433d6423SLionel Sambuc
88433d6423SLionel Sambuc
89433d6423SLionel Sambuc if (!StackPtr || !*StackPtr)
90433d6423SLionel Sambuc {
91433d6423SLionel Sambuc ACPI_ERROR ((AE_INFO, "Internal - null pointer"));
92433d6423SLionel Sambuc return_ACPI_STATUS (AE_AML_NO_OPERAND);
93433d6423SLionel Sambuc }
94433d6423SLionel Sambuc
95433d6423SLionel Sambuc /*
96433d6423SLionel Sambuc * The entity pointed to by the StackPtr can be either
97433d6423SLionel Sambuc * 1) A valid ACPI_OPERAND_OBJECT, or
98433d6423SLionel Sambuc * 2) A ACPI_NAMESPACE_NODE (NamedObj)
99433d6423SLionel Sambuc */
100433d6423SLionel Sambuc if (ACPI_GET_DESCRIPTOR_TYPE (*StackPtr) == ACPI_DESC_TYPE_OPERAND)
101433d6423SLionel Sambuc {
102433d6423SLionel Sambuc Status = AcpiExResolveObjectToValue (StackPtr, WalkState);
103433d6423SLionel Sambuc if (ACPI_FAILURE (Status))
104433d6423SLionel Sambuc {
105433d6423SLionel Sambuc return_ACPI_STATUS (Status);
106433d6423SLionel Sambuc }
107433d6423SLionel Sambuc
108433d6423SLionel Sambuc if (!*StackPtr)
109433d6423SLionel Sambuc {
110433d6423SLionel Sambuc ACPI_ERROR ((AE_INFO, "Internal - null pointer"));
111433d6423SLionel Sambuc return_ACPI_STATUS (AE_AML_NO_OPERAND);
112433d6423SLionel Sambuc }
113433d6423SLionel Sambuc }
114433d6423SLionel Sambuc
115433d6423SLionel Sambuc /*
116433d6423SLionel Sambuc * Object on the stack may have changed if AcpiExResolveObjectToValue()
117433d6423SLionel Sambuc * was called (i.e., we can't use an _else_ here.)
118433d6423SLionel Sambuc */
119433d6423SLionel Sambuc if (ACPI_GET_DESCRIPTOR_TYPE (*StackPtr) == ACPI_DESC_TYPE_NAMED)
120433d6423SLionel Sambuc {
121433d6423SLionel Sambuc Status = AcpiExResolveNodeToValue (
122433d6423SLionel Sambuc ACPI_CAST_INDIRECT_PTR (ACPI_NAMESPACE_NODE, StackPtr),
123433d6423SLionel Sambuc WalkState);
124433d6423SLionel Sambuc if (ACPI_FAILURE (Status))
125433d6423SLionel Sambuc {
126433d6423SLionel Sambuc return_ACPI_STATUS (Status);
127433d6423SLionel Sambuc }
128433d6423SLionel Sambuc }
129433d6423SLionel Sambuc
130433d6423SLionel Sambuc ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Resolved object %p\n", *StackPtr));
131433d6423SLionel Sambuc return_ACPI_STATUS (AE_OK);
132433d6423SLionel Sambuc }
133433d6423SLionel Sambuc
134433d6423SLionel Sambuc
135433d6423SLionel Sambuc /*******************************************************************************
136433d6423SLionel Sambuc *
137433d6423SLionel Sambuc * FUNCTION: AcpiExResolveObjectToValue
138433d6423SLionel Sambuc *
139433d6423SLionel Sambuc * PARAMETERS: StackPtr - Pointer to an internal object
140433d6423SLionel Sambuc * WalkState - Current method state
141433d6423SLionel Sambuc *
142433d6423SLionel Sambuc * RETURN: Status
143433d6423SLionel Sambuc *
144433d6423SLionel Sambuc * DESCRIPTION: Retrieve the value from an internal object. The Reference type
145433d6423SLionel Sambuc * uses the associated AML opcode to determine the value.
146433d6423SLionel Sambuc *
147433d6423SLionel Sambuc ******************************************************************************/
148433d6423SLionel Sambuc
149433d6423SLionel Sambuc static ACPI_STATUS
AcpiExResolveObjectToValue(ACPI_OPERAND_OBJECT ** StackPtr,ACPI_WALK_STATE * WalkState)150433d6423SLionel Sambuc AcpiExResolveObjectToValue (
151433d6423SLionel Sambuc ACPI_OPERAND_OBJECT **StackPtr,
152433d6423SLionel Sambuc ACPI_WALK_STATE *WalkState)
153433d6423SLionel Sambuc {
154433d6423SLionel Sambuc ACPI_STATUS Status = AE_OK;
155433d6423SLionel Sambuc ACPI_OPERAND_OBJECT *StackDesc;
156433d6423SLionel Sambuc ACPI_OPERAND_OBJECT *ObjDesc = NULL;
157433d6423SLionel Sambuc UINT8 RefType;
158433d6423SLionel Sambuc
159433d6423SLionel Sambuc
160433d6423SLionel Sambuc ACPI_FUNCTION_TRACE (ExResolveObjectToValue);
161433d6423SLionel Sambuc
162433d6423SLionel Sambuc
163433d6423SLionel Sambuc StackDesc = *StackPtr;
164433d6423SLionel Sambuc
165*29492bb7SDavid van Moolenbroek /* This is an object of type ACPI_OPERAND_OBJECT */
166433d6423SLionel Sambuc
167433d6423SLionel Sambuc switch (StackDesc->Common.Type)
168433d6423SLionel Sambuc {
169433d6423SLionel Sambuc case ACPI_TYPE_LOCAL_REFERENCE:
170433d6423SLionel Sambuc
171433d6423SLionel Sambuc RefType = StackDesc->Reference.Class;
172433d6423SLionel Sambuc
173433d6423SLionel Sambuc switch (RefType)
174433d6423SLionel Sambuc {
175433d6423SLionel Sambuc case ACPI_REFCLASS_LOCAL:
176433d6423SLionel Sambuc case ACPI_REFCLASS_ARG:
177433d6423SLionel Sambuc /*
178433d6423SLionel Sambuc * Get the local from the method's state info
179433d6423SLionel Sambuc * Note: this increments the local's object reference count
180433d6423SLionel Sambuc */
181433d6423SLionel Sambuc Status = AcpiDsMethodDataGetValue (RefType,
182433d6423SLionel Sambuc StackDesc->Reference.Value, WalkState, &ObjDesc);
183433d6423SLionel Sambuc if (ACPI_FAILURE (Status))
184433d6423SLionel Sambuc {
185433d6423SLionel Sambuc return_ACPI_STATUS (Status);
186433d6423SLionel Sambuc }
187433d6423SLionel Sambuc
188433d6423SLionel Sambuc ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[Arg/Local %X] ValueObj is %p\n",
189433d6423SLionel Sambuc StackDesc->Reference.Value, ObjDesc));
190433d6423SLionel Sambuc
191433d6423SLionel Sambuc /*
192433d6423SLionel Sambuc * Now we can delete the original Reference Object and
193433d6423SLionel Sambuc * replace it with the resolved value
194433d6423SLionel Sambuc */
195433d6423SLionel Sambuc AcpiUtRemoveReference (StackDesc);
196433d6423SLionel Sambuc *StackPtr = ObjDesc;
197433d6423SLionel Sambuc break;
198433d6423SLionel Sambuc
199433d6423SLionel Sambuc case ACPI_REFCLASS_INDEX:
200433d6423SLionel Sambuc
201433d6423SLionel Sambuc switch (StackDesc->Reference.TargetType)
202433d6423SLionel Sambuc {
203433d6423SLionel Sambuc case ACPI_TYPE_BUFFER_FIELD:
204433d6423SLionel Sambuc
205433d6423SLionel Sambuc /* Just return - do not dereference */
206433d6423SLionel Sambuc break;
207433d6423SLionel Sambuc
208433d6423SLionel Sambuc case ACPI_TYPE_PACKAGE:
209433d6423SLionel Sambuc
210433d6423SLionel Sambuc /* If method call or CopyObject - do not dereference */
211433d6423SLionel Sambuc
212433d6423SLionel Sambuc if ((WalkState->Opcode == AML_INT_METHODCALL_OP) ||
213433d6423SLionel Sambuc (WalkState->Opcode == AML_COPY_OP))
214433d6423SLionel Sambuc {
215433d6423SLionel Sambuc break;
216433d6423SLionel Sambuc }
217433d6423SLionel Sambuc
218433d6423SLionel Sambuc /* Otherwise, dereference the PackageIndex to a package element */
219433d6423SLionel Sambuc
220433d6423SLionel Sambuc ObjDesc = *StackDesc->Reference.Where;
221433d6423SLionel Sambuc if (ObjDesc)
222433d6423SLionel Sambuc {
223433d6423SLionel Sambuc /*
224433d6423SLionel Sambuc * Valid object descriptor, copy pointer to return value
225433d6423SLionel Sambuc * (i.e., dereference the package index)
226433d6423SLionel Sambuc * Delete the ref object, increment the returned object
227433d6423SLionel Sambuc */
228433d6423SLionel Sambuc AcpiUtRemoveReference (StackDesc);
229433d6423SLionel Sambuc AcpiUtAddReference (ObjDesc);
230433d6423SLionel Sambuc *StackPtr = ObjDesc;
231433d6423SLionel Sambuc }
232433d6423SLionel Sambuc else
233433d6423SLionel Sambuc {
234433d6423SLionel Sambuc /*
235433d6423SLionel Sambuc * A NULL object descriptor means an uninitialized element of
236433d6423SLionel Sambuc * the package, can't dereference it
237433d6423SLionel Sambuc */
238433d6423SLionel Sambuc ACPI_ERROR ((AE_INFO,
239433d6423SLionel Sambuc "Attempt to dereference an Index to NULL package element Idx=%p",
240433d6423SLionel Sambuc StackDesc));
241433d6423SLionel Sambuc Status = AE_AML_UNINITIALIZED_ELEMENT;
242433d6423SLionel Sambuc }
243433d6423SLionel Sambuc break;
244433d6423SLionel Sambuc
245433d6423SLionel Sambuc default:
246433d6423SLionel Sambuc
247433d6423SLionel Sambuc /* Invalid reference object */
248433d6423SLionel Sambuc
249433d6423SLionel Sambuc ACPI_ERROR ((AE_INFO,
250433d6423SLionel Sambuc "Unknown TargetType 0x%X in Index/Reference object %p",
251433d6423SLionel Sambuc StackDesc->Reference.TargetType, StackDesc));
252433d6423SLionel Sambuc Status = AE_AML_INTERNAL;
253433d6423SLionel Sambuc break;
254433d6423SLionel Sambuc }
255433d6423SLionel Sambuc break;
256433d6423SLionel Sambuc
257433d6423SLionel Sambuc case ACPI_REFCLASS_REFOF:
258433d6423SLionel Sambuc case ACPI_REFCLASS_DEBUG:
259433d6423SLionel Sambuc case ACPI_REFCLASS_TABLE:
260433d6423SLionel Sambuc
261433d6423SLionel Sambuc /* Just leave the object as-is, do not dereference */
262433d6423SLionel Sambuc
263433d6423SLionel Sambuc break;
264433d6423SLionel Sambuc
265433d6423SLionel Sambuc case ACPI_REFCLASS_NAME: /* Reference to a named object */
266433d6423SLionel Sambuc
267433d6423SLionel Sambuc /* Dereference the name */
268433d6423SLionel Sambuc
269433d6423SLionel Sambuc if ((StackDesc->Reference.Node->Type == ACPI_TYPE_DEVICE) ||
270433d6423SLionel Sambuc (StackDesc->Reference.Node->Type == ACPI_TYPE_THERMAL))
271433d6423SLionel Sambuc {
272433d6423SLionel Sambuc /* These node types do not have 'real' subobjects */
273433d6423SLionel Sambuc
274433d6423SLionel Sambuc *StackPtr = (void *) StackDesc->Reference.Node;
275433d6423SLionel Sambuc }
276433d6423SLionel Sambuc else
277433d6423SLionel Sambuc {
278433d6423SLionel Sambuc /* Get the object pointed to by the namespace node */
279433d6423SLionel Sambuc
280433d6423SLionel Sambuc *StackPtr = (StackDesc->Reference.Node)->Object;
281433d6423SLionel Sambuc AcpiUtAddReference (*StackPtr);
282433d6423SLionel Sambuc }
283433d6423SLionel Sambuc
284433d6423SLionel Sambuc AcpiUtRemoveReference (StackDesc);
285433d6423SLionel Sambuc break;
286433d6423SLionel Sambuc
287433d6423SLionel Sambuc default:
288433d6423SLionel Sambuc
289433d6423SLionel Sambuc ACPI_ERROR ((AE_INFO,
290433d6423SLionel Sambuc "Unknown Reference type 0x%X in %p", RefType, StackDesc));
291433d6423SLionel Sambuc Status = AE_AML_INTERNAL;
292433d6423SLionel Sambuc break;
293433d6423SLionel Sambuc }
294433d6423SLionel Sambuc break;
295433d6423SLionel Sambuc
296433d6423SLionel Sambuc case ACPI_TYPE_BUFFER:
297433d6423SLionel Sambuc
298433d6423SLionel Sambuc Status = AcpiDsGetBufferArguments (StackDesc);
299433d6423SLionel Sambuc break;
300433d6423SLionel Sambuc
301433d6423SLionel Sambuc case ACPI_TYPE_PACKAGE:
302433d6423SLionel Sambuc
303433d6423SLionel Sambuc Status = AcpiDsGetPackageArguments (StackDesc);
304433d6423SLionel Sambuc break;
305433d6423SLionel Sambuc
306433d6423SLionel Sambuc case ACPI_TYPE_BUFFER_FIELD:
307433d6423SLionel Sambuc case ACPI_TYPE_LOCAL_REGION_FIELD:
308433d6423SLionel Sambuc case ACPI_TYPE_LOCAL_BANK_FIELD:
309433d6423SLionel Sambuc case ACPI_TYPE_LOCAL_INDEX_FIELD:
310433d6423SLionel Sambuc
311433d6423SLionel Sambuc ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "FieldRead SourceDesc=%p Type=%X\n",
312433d6423SLionel Sambuc StackDesc, StackDesc->Common.Type));
313433d6423SLionel Sambuc
314433d6423SLionel Sambuc Status = AcpiExReadDataFromField (WalkState, StackDesc, &ObjDesc);
315433d6423SLionel Sambuc
316433d6423SLionel Sambuc /* Remove a reference to the original operand, then override */
317433d6423SLionel Sambuc
318433d6423SLionel Sambuc AcpiUtRemoveReference (*StackPtr);
319433d6423SLionel Sambuc *StackPtr = (void *) ObjDesc;
320433d6423SLionel Sambuc break;
321433d6423SLionel Sambuc
322433d6423SLionel Sambuc default:
323*29492bb7SDavid van Moolenbroek
324433d6423SLionel Sambuc break;
325433d6423SLionel Sambuc }
326433d6423SLionel Sambuc
327433d6423SLionel Sambuc return_ACPI_STATUS (Status);
328433d6423SLionel Sambuc }
329433d6423SLionel Sambuc
330433d6423SLionel Sambuc
331433d6423SLionel Sambuc /*******************************************************************************
332433d6423SLionel Sambuc *
333433d6423SLionel Sambuc * FUNCTION: AcpiExResolveMultiple
334433d6423SLionel Sambuc *
335433d6423SLionel Sambuc * PARAMETERS: WalkState - Current state (contains AML opcode)
336433d6423SLionel Sambuc * Operand - Starting point for resolution
337433d6423SLionel Sambuc * ReturnType - Where the object type is returned
338433d6423SLionel Sambuc * ReturnDesc - Where the resolved object is returned
339433d6423SLionel Sambuc *
340433d6423SLionel Sambuc * RETURN: Status
341433d6423SLionel Sambuc *
342433d6423SLionel Sambuc * DESCRIPTION: Return the base object and type. Traverse a reference list if
343433d6423SLionel Sambuc * necessary to get to the base object.
344433d6423SLionel Sambuc *
345433d6423SLionel Sambuc ******************************************************************************/
346433d6423SLionel Sambuc
347433d6423SLionel Sambuc ACPI_STATUS
AcpiExResolveMultiple(ACPI_WALK_STATE * WalkState,ACPI_OPERAND_OBJECT * Operand,ACPI_OBJECT_TYPE * ReturnType,ACPI_OPERAND_OBJECT ** ReturnDesc)348433d6423SLionel Sambuc AcpiExResolveMultiple (
349433d6423SLionel Sambuc ACPI_WALK_STATE *WalkState,
350433d6423SLionel Sambuc ACPI_OPERAND_OBJECT *Operand,
351433d6423SLionel Sambuc ACPI_OBJECT_TYPE *ReturnType,
352433d6423SLionel Sambuc ACPI_OPERAND_OBJECT **ReturnDesc)
353433d6423SLionel Sambuc {
354433d6423SLionel Sambuc ACPI_OPERAND_OBJECT *ObjDesc = (void *) Operand;
355433d6423SLionel Sambuc ACPI_NAMESPACE_NODE *Node;
356433d6423SLionel Sambuc ACPI_OBJECT_TYPE Type;
357433d6423SLionel Sambuc ACPI_STATUS Status;
358433d6423SLionel Sambuc
359433d6423SLionel Sambuc
360433d6423SLionel Sambuc ACPI_FUNCTION_TRACE (AcpiExResolveMultiple);
361433d6423SLionel Sambuc
362433d6423SLionel Sambuc
363433d6423SLionel Sambuc /* Operand can be either a namespace node or an operand descriptor */
364433d6423SLionel Sambuc
365433d6423SLionel Sambuc switch (ACPI_GET_DESCRIPTOR_TYPE (ObjDesc))
366433d6423SLionel Sambuc {
367433d6423SLionel Sambuc case ACPI_DESC_TYPE_OPERAND:
368*29492bb7SDavid van Moolenbroek
369433d6423SLionel Sambuc Type = ObjDesc->Common.Type;
370433d6423SLionel Sambuc break;
371433d6423SLionel Sambuc
372433d6423SLionel Sambuc case ACPI_DESC_TYPE_NAMED:
373*29492bb7SDavid van Moolenbroek
374433d6423SLionel Sambuc Type = ((ACPI_NAMESPACE_NODE *) ObjDesc)->Type;
375433d6423SLionel Sambuc ObjDesc = AcpiNsGetAttachedObject ((ACPI_NAMESPACE_NODE *) ObjDesc);
376433d6423SLionel Sambuc
377433d6423SLionel Sambuc /* If we had an Alias node, use the attached object for type info */
378433d6423SLionel Sambuc
379433d6423SLionel Sambuc if (Type == ACPI_TYPE_LOCAL_ALIAS)
380433d6423SLionel Sambuc {
381433d6423SLionel Sambuc Type = ((ACPI_NAMESPACE_NODE *) ObjDesc)->Type;
382433d6423SLionel Sambuc ObjDesc = AcpiNsGetAttachedObject ((ACPI_NAMESPACE_NODE *) ObjDesc);
383433d6423SLionel Sambuc }
384433d6423SLionel Sambuc break;
385433d6423SLionel Sambuc
386433d6423SLionel Sambuc default:
387433d6423SLionel Sambuc return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
388433d6423SLionel Sambuc }
389433d6423SLionel Sambuc
390433d6423SLionel Sambuc /* If type is anything other than a reference, we are done */
391433d6423SLionel Sambuc
392433d6423SLionel Sambuc if (Type != ACPI_TYPE_LOCAL_REFERENCE)
393433d6423SLionel Sambuc {
394433d6423SLionel Sambuc goto Exit;
395433d6423SLionel Sambuc }
396433d6423SLionel Sambuc
397433d6423SLionel Sambuc /*
398433d6423SLionel Sambuc * For reference objects created via the RefOf, Index, or Load/LoadTable
399433d6423SLionel Sambuc * operators, we need to get to the base object (as per the ACPI
400433d6423SLionel Sambuc * specification of the ObjectType and SizeOf operators). This means
401433d6423SLionel Sambuc * traversing the list of possibly many nested references.
402433d6423SLionel Sambuc */
403433d6423SLionel Sambuc while (ObjDesc->Common.Type == ACPI_TYPE_LOCAL_REFERENCE)
404433d6423SLionel Sambuc {
405433d6423SLionel Sambuc switch (ObjDesc->Reference.Class)
406433d6423SLionel Sambuc {
407433d6423SLionel Sambuc case ACPI_REFCLASS_REFOF:
408433d6423SLionel Sambuc case ACPI_REFCLASS_NAME:
409433d6423SLionel Sambuc
410433d6423SLionel Sambuc /* Dereference the reference pointer */
411433d6423SLionel Sambuc
412433d6423SLionel Sambuc if (ObjDesc->Reference.Class == ACPI_REFCLASS_REFOF)
413433d6423SLionel Sambuc {
414433d6423SLionel Sambuc Node = ObjDesc->Reference.Object;
415433d6423SLionel Sambuc }
416433d6423SLionel Sambuc else /* AML_INT_NAMEPATH_OP */
417433d6423SLionel Sambuc {
418433d6423SLionel Sambuc Node = ObjDesc->Reference.Node;
419433d6423SLionel Sambuc }
420433d6423SLionel Sambuc
421433d6423SLionel Sambuc /* All "References" point to a NS node */
422433d6423SLionel Sambuc
423433d6423SLionel Sambuc if (ACPI_GET_DESCRIPTOR_TYPE (Node) != ACPI_DESC_TYPE_NAMED)
424433d6423SLionel Sambuc {
425433d6423SLionel Sambuc ACPI_ERROR ((AE_INFO,
426433d6423SLionel Sambuc "Not a namespace node %p [%s]",
427433d6423SLionel Sambuc Node, AcpiUtGetDescriptorName (Node)));
428433d6423SLionel Sambuc return_ACPI_STATUS (AE_AML_INTERNAL);
429433d6423SLionel Sambuc }
430433d6423SLionel Sambuc
431433d6423SLionel Sambuc /* Get the attached object */
432433d6423SLionel Sambuc
433433d6423SLionel Sambuc ObjDesc = AcpiNsGetAttachedObject (Node);
434433d6423SLionel Sambuc if (!ObjDesc)
435433d6423SLionel Sambuc {
436433d6423SLionel Sambuc /* No object, use the NS node type */
437433d6423SLionel Sambuc
438433d6423SLionel Sambuc Type = AcpiNsGetType (Node);
439433d6423SLionel Sambuc goto Exit;
440433d6423SLionel Sambuc }
441433d6423SLionel Sambuc
442433d6423SLionel Sambuc /* Check for circular references */
443433d6423SLionel Sambuc
444433d6423SLionel Sambuc if (ObjDesc == Operand)
445433d6423SLionel Sambuc {
446433d6423SLionel Sambuc return_ACPI_STATUS (AE_AML_CIRCULAR_REFERENCE);
447433d6423SLionel Sambuc }
448433d6423SLionel Sambuc break;
449433d6423SLionel Sambuc
450433d6423SLionel Sambuc case ACPI_REFCLASS_INDEX:
451433d6423SLionel Sambuc
452433d6423SLionel Sambuc /* Get the type of this reference (index into another object) */
453433d6423SLionel Sambuc
454433d6423SLionel Sambuc Type = ObjDesc->Reference.TargetType;
455433d6423SLionel Sambuc if (Type != ACPI_TYPE_PACKAGE)
456433d6423SLionel Sambuc {
457433d6423SLionel Sambuc goto Exit;
458433d6423SLionel Sambuc }
459433d6423SLionel Sambuc
460433d6423SLionel Sambuc /*
461433d6423SLionel Sambuc * The main object is a package, we want to get the type
462433d6423SLionel Sambuc * of the individual package element that is referenced by
463433d6423SLionel Sambuc * the index.
464433d6423SLionel Sambuc *
465433d6423SLionel Sambuc * This could of course in turn be another reference object.
466433d6423SLionel Sambuc */
467433d6423SLionel Sambuc ObjDesc = *(ObjDesc->Reference.Where);
468433d6423SLionel Sambuc if (!ObjDesc)
469433d6423SLionel Sambuc {
470433d6423SLionel Sambuc /* NULL package elements are allowed */
471433d6423SLionel Sambuc
472433d6423SLionel Sambuc Type = 0; /* Uninitialized */
473433d6423SLionel Sambuc goto Exit;
474433d6423SLionel Sambuc }
475433d6423SLionel Sambuc break;
476433d6423SLionel Sambuc
477433d6423SLionel Sambuc case ACPI_REFCLASS_TABLE:
478433d6423SLionel Sambuc
479433d6423SLionel Sambuc Type = ACPI_TYPE_DDB_HANDLE;
480433d6423SLionel Sambuc goto Exit;
481433d6423SLionel Sambuc
482433d6423SLionel Sambuc case ACPI_REFCLASS_LOCAL:
483433d6423SLionel Sambuc case ACPI_REFCLASS_ARG:
484433d6423SLionel Sambuc
485433d6423SLionel Sambuc if (ReturnDesc)
486433d6423SLionel Sambuc {
487433d6423SLionel Sambuc Status = AcpiDsMethodDataGetValue (ObjDesc->Reference.Class,
488433d6423SLionel Sambuc ObjDesc->Reference.Value, WalkState, &ObjDesc);
489433d6423SLionel Sambuc if (ACPI_FAILURE (Status))
490433d6423SLionel Sambuc {
491433d6423SLionel Sambuc return_ACPI_STATUS (Status);
492433d6423SLionel Sambuc }
493433d6423SLionel Sambuc AcpiUtRemoveReference (ObjDesc);
494433d6423SLionel Sambuc }
495433d6423SLionel Sambuc else
496433d6423SLionel Sambuc {
497433d6423SLionel Sambuc Status = AcpiDsMethodDataGetNode (ObjDesc->Reference.Class,
498433d6423SLionel Sambuc ObjDesc->Reference.Value, WalkState, &Node);
499433d6423SLionel Sambuc if (ACPI_FAILURE (Status))
500433d6423SLionel Sambuc {
501433d6423SLionel Sambuc return_ACPI_STATUS (Status);
502433d6423SLionel Sambuc }
503433d6423SLionel Sambuc
504433d6423SLionel Sambuc ObjDesc = AcpiNsGetAttachedObject (Node);
505433d6423SLionel Sambuc if (!ObjDesc)
506433d6423SLionel Sambuc {
507433d6423SLionel Sambuc Type = ACPI_TYPE_ANY;
508433d6423SLionel Sambuc goto Exit;
509433d6423SLionel Sambuc }
510433d6423SLionel Sambuc }
511433d6423SLionel Sambuc break;
512433d6423SLionel Sambuc
513433d6423SLionel Sambuc case ACPI_REFCLASS_DEBUG:
514433d6423SLionel Sambuc
515433d6423SLionel Sambuc /* The Debug Object is of type "DebugObject" */
516433d6423SLionel Sambuc
517433d6423SLionel Sambuc Type = ACPI_TYPE_DEBUG_OBJECT;
518433d6423SLionel Sambuc goto Exit;
519433d6423SLionel Sambuc
520433d6423SLionel Sambuc default:
521433d6423SLionel Sambuc
522433d6423SLionel Sambuc ACPI_ERROR ((AE_INFO,
523433d6423SLionel Sambuc "Unknown Reference Class 0x%2.2X", ObjDesc->Reference.Class));
524433d6423SLionel Sambuc return_ACPI_STATUS (AE_AML_INTERNAL);
525433d6423SLionel Sambuc }
526433d6423SLionel Sambuc }
527433d6423SLionel Sambuc
528433d6423SLionel Sambuc /*
529433d6423SLionel Sambuc * Now we are guaranteed to have an object that has not been created
530433d6423SLionel Sambuc * via the RefOf or Index operators.
531433d6423SLionel Sambuc */
532433d6423SLionel Sambuc Type = ObjDesc->Common.Type;
533433d6423SLionel Sambuc
534433d6423SLionel Sambuc
535433d6423SLionel Sambuc Exit:
536433d6423SLionel Sambuc /* Convert internal types to external types */
537433d6423SLionel Sambuc
538433d6423SLionel Sambuc switch (Type)
539433d6423SLionel Sambuc {
540433d6423SLionel Sambuc case ACPI_TYPE_LOCAL_REGION_FIELD:
541433d6423SLionel Sambuc case ACPI_TYPE_LOCAL_BANK_FIELD:
542433d6423SLionel Sambuc case ACPI_TYPE_LOCAL_INDEX_FIELD:
543433d6423SLionel Sambuc
544433d6423SLionel Sambuc Type = ACPI_TYPE_FIELD_UNIT;
545433d6423SLionel Sambuc break;
546433d6423SLionel Sambuc
547433d6423SLionel Sambuc case ACPI_TYPE_LOCAL_SCOPE:
548433d6423SLionel Sambuc
549433d6423SLionel Sambuc /* Per ACPI Specification, Scope is untyped */
550433d6423SLionel Sambuc
551433d6423SLionel Sambuc Type = ACPI_TYPE_ANY;
552433d6423SLionel Sambuc break;
553433d6423SLionel Sambuc
554433d6423SLionel Sambuc default:
555*29492bb7SDavid van Moolenbroek
556433d6423SLionel Sambuc /* No change to Type required */
557*29492bb7SDavid van Moolenbroek
558433d6423SLionel Sambuc break;
559433d6423SLionel Sambuc }
560433d6423SLionel Sambuc
561433d6423SLionel Sambuc *ReturnType = Type;
562433d6423SLionel Sambuc if (ReturnDesc)
563433d6423SLionel Sambuc {
564433d6423SLionel Sambuc *ReturnDesc = ObjDesc;
565433d6423SLionel Sambuc }
566433d6423SLionel Sambuc return_ACPI_STATUS (AE_OK);
567433d6423SLionel Sambuc }
568