1*4882a593Smuzhiyun // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
2*4882a593Smuzhiyun /******************************************************************************
3*4882a593Smuzhiyun *
4*4882a593Smuzhiyun * Module Name: exresolv - AML Interpreter object resolution
5*4882a593Smuzhiyun *
6*4882a593Smuzhiyun * Copyright (C) 2000 - 2020, Intel Corp.
7*4882a593Smuzhiyun *
8*4882a593Smuzhiyun *****************************************************************************/
9*4882a593Smuzhiyun
10*4882a593Smuzhiyun #include <acpi/acpi.h>
11*4882a593Smuzhiyun #include "accommon.h"
12*4882a593Smuzhiyun #include "amlcode.h"
13*4882a593Smuzhiyun #include "acdispat.h"
14*4882a593Smuzhiyun #include "acinterp.h"
15*4882a593Smuzhiyun #include "acnamesp.h"
16*4882a593Smuzhiyun
17*4882a593Smuzhiyun #define _COMPONENT ACPI_EXECUTER
18*4882a593Smuzhiyun ACPI_MODULE_NAME("exresolv")
19*4882a593Smuzhiyun
20*4882a593Smuzhiyun /* Local prototypes */
21*4882a593Smuzhiyun static acpi_status
22*4882a593Smuzhiyun acpi_ex_resolve_object_to_value(union acpi_operand_object **stack_ptr,
23*4882a593Smuzhiyun struct acpi_walk_state *walk_state);
24*4882a593Smuzhiyun
25*4882a593Smuzhiyun /*******************************************************************************
26*4882a593Smuzhiyun *
27*4882a593Smuzhiyun * FUNCTION: acpi_ex_resolve_to_value
28*4882a593Smuzhiyun *
29*4882a593Smuzhiyun * PARAMETERS: **stack_ptr - Points to entry on obj_stack, which can
30*4882a593Smuzhiyun * be either an (union acpi_operand_object *)
31*4882a593Smuzhiyun * or an acpi_handle.
32*4882a593Smuzhiyun * walk_state - Current method state
33*4882a593Smuzhiyun *
34*4882a593Smuzhiyun * RETURN: Status
35*4882a593Smuzhiyun *
36*4882a593Smuzhiyun * DESCRIPTION: Convert Reference objects to values
37*4882a593Smuzhiyun *
38*4882a593Smuzhiyun ******************************************************************************/
39*4882a593Smuzhiyun
40*4882a593Smuzhiyun acpi_status
acpi_ex_resolve_to_value(union acpi_operand_object ** stack_ptr,struct acpi_walk_state * walk_state)41*4882a593Smuzhiyun acpi_ex_resolve_to_value(union acpi_operand_object **stack_ptr,
42*4882a593Smuzhiyun struct acpi_walk_state *walk_state)
43*4882a593Smuzhiyun {
44*4882a593Smuzhiyun acpi_status status;
45*4882a593Smuzhiyun
46*4882a593Smuzhiyun ACPI_FUNCTION_TRACE_PTR(ex_resolve_to_value, stack_ptr);
47*4882a593Smuzhiyun
48*4882a593Smuzhiyun if (!stack_ptr || !*stack_ptr) {
49*4882a593Smuzhiyun ACPI_ERROR((AE_INFO, "Internal - null pointer"));
50*4882a593Smuzhiyun return_ACPI_STATUS(AE_AML_NO_OPERAND);
51*4882a593Smuzhiyun }
52*4882a593Smuzhiyun
53*4882a593Smuzhiyun /*
54*4882a593Smuzhiyun * The entity pointed to by the stack_ptr can be either
55*4882a593Smuzhiyun * 1) A valid union acpi_operand_object, or
56*4882a593Smuzhiyun * 2) A struct acpi_namespace_node (named_obj)
57*4882a593Smuzhiyun */
58*4882a593Smuzhiyun if (ACPI_GET_DESCRIPTOR_TYPE(*stack_ptr) == ACPI_DESC_TYPE_OPERAND) {
59*4882a593Smuzhiyun status = acpi_ex_resolve_object_to_value(stack_ptr, walk_state);
60*4882a593Smuzhiyun if (ACPI_FAILURE(status)) {
61*4882a593Smuzhiyun return_ACPI_STATUS(status);
62*4882a593Smuzhiyun }
63*4882a593Smuzhiyun
64*4882a593Smuzhiyun if (!*stack_ptr) {
65*4882a593Smuzhiyun ACPI_ERROR((AE_INFO, "Internal - null pointer"));
66*4882a593Smuzhiyun return_ACPI_STATUS(AE_AML_NO_OPERAND);
67*4882a593Smuzhiyun }
68*4882a593Smuzhiyun }
69*4882a593Smuzhiyun
70*4882a593Smuzhiyun /*
71*4882a593Smuzhiyun * Object on the stack may have changed if acpi_ex_resolve_object_to_value()
72*4882a593Smuzhiyun * was called (i.e., we can't use an _else_ here.)
73*4882a593Smuzhiyun */
74*4882a593Smuzhiyun if (ACPI_GET_DESCRIPTOR_TYPE(*stack_ptr) == ACPI_DESC_TYPE_NAMED) {
75*4882a593Smuzhiyun status =
76*4882a593Smuzhiyun acpi_ex_resolve_node_to_value(ACPI_CAST_INDIRECT_PTR
77*4882a593Smuzhiyun (struct acpi_namespace_node,
78*4882a593Smuzhiyun stack_ptr), walk_state);
79*4882a593Smuzhiyun if (ACPI_FAILURE(status)) {
80*4882a593Smuzhiyun return_ACPI_STATUS(status);
81*4882a593Smuzhiyun }
82*4882a593Smuzhiyun }
83*4882a593Smuzhiyun
84*4882a593Smuzhiyun ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Resolved object %p\n", *stack_ptr));
85*4882a593Smuzhiyun return_ACPI_STATUS(AE_OK);
86*4882a593Smuzhiyun }
87*4882a593Smuzhiyun
88*4882a593Smuzhiyun /*******************************************************************************
89*4882a593Smuzhiyun *
90*4882a593Smuzhiyun * FUNCTION: acpi_ex_resolve_object_to_value
91*4882a593Smuzhiyun *
92*4882a593Smuzhiyun * PARAMETERS: stack_ptr - Pointer to an internal object
93*4882a593Smuzhiyun * walk_state - Current method state
94*4882a593Smuzhiyun *
95*4882a593Smuzhiyun * RETURN: Status
96*4882a593Smuzhiyun *
97*4882a593Smuzhiyun * DESCRIPTION: Retrieve the value from an internal object. The Reference type
98*4882a593Smuzhiyun * uses the associated AML opcode to determine the value.
99*4882a593Smuzhiyun *
100*4882a593Smuzhiyun ******************************************************************************/
101*4882a593Smuzhiyun
102*4882a593Smuzhiyun static acpi_status
acpi_ex_resolve_object_to_value(union acpi_operand_object ** stack_ptr,struct acpi_walk_state * walk_state)103*4882a593Smuzhiyun acpi_ex_resolve_object_to_value(union acpi_operand_object **stack_ptr,
104*4882a593Smuzhiyun struct acpi_walk_state *walk_state)
105*4882a593Smuzhiyun {
106*4882a593Smuzhiyun acpi_status status = AE_OK;
107*4882a593Smuzhiyun union acpi_operand_object *stack_desc;
108*4882a593Smuzhiyun union acpi_operand_object *obj_desc = NULL;
109*4882a593Smuzhiyun u8 ref_type;
110*4882a593Smuzhiyun
111*4882a593Smuzhiyun ACPI_FUNCTION_TRACE(ex_resolve_object_to_value);
112*4882a593Smuzhiyun
113*4882a593Smuzhiyun stack_desc = *stack_ptr;
114*4882a593Smuzhiyun
115*4882a593Smuzhiyun /* This is an object of type union acpi_operand_object */
116*4882a593Smuzhiyun
117*4882a593Smuzhiyun switch (stack_desc->common.type) {
118*4882a593Smuzhiyun case ACPI_TYPE_LOCAL_REFERENCE:
119*4882a593Smuzhiyun
120*4882a593Smuzhiyun ref_type = stack_desc->reference.class;
121*4882a593Smuzhiyun
122*4882a593Smuzhiyun switch (ref_type) {
123*4882a593Smuzhiyun case ACPI_REFCLASS_LOCAL:
124*4882a593Smuzhiyun case ACPI_REFCLASS_ARG:
125*4882a593Smuzhiyun /*
126*4882a593Smuzhiyun * Get the local from the method's state info
127*4882a593Smuzhiyun * Note: this increments the local's object reference count
128*4882a593Smuzhiyun */
129*4882a593Smuzhiyun status = acpi_ds_method_data_get_value(ref_type,
130*4882a593Smuzhiyun stack_desc->
131*4882a593Smuzhiyun reference.value,
132*4882a593Smuzhiyun walk_state,
133*4882a593Smuzhiyun &obj_desc);
134*4882a593Smuzhiyun if (ACPI_FAILURE(status)) {
135*4882a593Smuzhiyun return_ACPI_STATUS(status);
136*4882a593Smuzhiyun }
137*4882a593Smuzhiyun
138*4882a593Smuzhiyun ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
139*4882a593Smuzhiyun "[Arg/Local %X] ValueObj is %p\n",
140*4882a593Smuzhiyun stack_desc->reference.value,
141*4882a593Smuzhiyun obj_desc));
142*4882a593Smuzhiyun
143*4882a593Smuzhiyun /*
144*4882a593Smuzhiyun * Now we can delete the original Reference Object and
145*4882a593Smuzhiyun * replace it with the resolved value
146*4882a593Smuzhiyun */
147*4882a593Smuzhiyun acpi_ut_remove_reference(stack_desc);
148*4882a593Smuzhiyun *stack_ptr = obj_desc;
149*4882a593Smuzhiyun break;
150*4882a593Smuzhiyun
151*4882a593Smuzhiyun case ACPI_REFCLASS_INDEX:
152*4882a593Smuzhiyun
153*4882a593Smuzhiyun switch (stack_desc->reference.target_type) {
154*4882a593Smuzhiyun case ACPI_TYPE_BUFFER_FIELD:
155*4882a593Smuzhiyun
156*4882a593Smuzhiyun /* Just return - do not dereference */
157*4882a593Smuzhiyun break;
158*4882a593Smuzhiyun
159*4882a593Smuzhiyun case ACPI_TYPE_PACKAGE:
160*4882a593Smuzhiyun
161*4882a593Smuzhiyun /* If method call or copy_object - do not dereference */
162*4882a593Smuzhiyun
163*4882a593Smuzhiyun if ((walk_state->opcode ==
164*4882a593Smuzhiyun AML_INT_METHODCALL_OP)
165*4882a593Smuzhiyun || (walk_state->opcode ==
166*4882a593Smuzhiyun AML_COPY_OBJECT_OP)) {
167*4882a593Smuzhiyun break;
168*4882a593Smuzhiyun }
169*4882a593Smuzhiyun
170*4882a593Smuzhiyun /* Otherwise, dereference the package_index to a package element */
171*4882a593Smuzhiyun
172*4882a593Smuzhiyun obj_desc = *stack_desc->reference.where;
173*4882a593Smuzhiyun if (obj_desc) {
174*4882a593Smuzhiyun /*
175*4882a593Smuzhiyun * Valid object descriptor, copy pointer to return value
176*4882a593Smuzhiyun * (i.e., dereference the package index)
177*4882a593Smuzhiyun * Delete the ref object, increment the returned object
178*4882a593Smuzhiyun */
179*4882a593Smuzhiyun acpi_ut_add_reference(obj_desc);
180*4882a593Smuzhiyun *stack_ptr = obj_desc;
181*4882a593Smuzhiyun } else {
182*4882a593Smuzhiyun /*
183*4882a593Smuzhiyun * A NULL object descriptor means an uninitialized element of
184*4882a593Smuzhiyun * the package, can't dereference it
185*4882a593Smuzhiyun */
186*4882a593Smuzhiyun ACPI_ERROR((AE_INFO,
187*4882a593Smuzhiyun "Attempt to dereference an Index to "
188*4882a593Smuzhiyun "NULL package element Idx=%p",
189*4882a593Smuzhiyun stack_desc));
190*4882a593Smuzhiyun status = AE_AML_UNINITIALIZED_ELEMENT;
191*4882a593Smuzhiyun }
192*4882a593Smuzhiyun break;
193*4882a593Smuzhiyun
194*4882a593Smuzhiyun default:
195*4882a593Smuzhiyun
196*4882a593Smuzhiyun /* Invalid reference object */
197*4882a593Smuzhiyun
198*4882a593Smuzhiyun ACPI_ERROR((AE_INFO,
199*4882a593Smuzhiyun "Unknown TargetType 0x%X in Index/Reference object %p",
200*4882a593Smuzhiyun stack_desc->reference.target_type,
201*4882a593Smuzhiyun stack_desc));
202*4882a593Smuzhiyun status = AE_AML_INTERNAL;
203*4882a593Smuzhiyun break;
204*4882a593Smuzhiyun }
205*4882a593Smuzhiyun break;
206*4882a593Smuzhiyun
207*4882a593Smuzhiyun case ACPI_REFCLASS_REFOF:
208*4882a593Smuzhiyun case ACPI_REFCLASS_DEBUG:
209*4882a593Smuzhiyun case ACPI_REFCLASS_TABLE:
210*4882a593Smuzhiyun
211*4882a593Smuzhiyun /* Just leave the object as-is, do not dereference */
212*4882a593Smuzhiyun
213*4882a593Smuzhiyun break;
214*4882a593Smuzhiyun
215*4882a593Smuzhiyun case ACPI_REFCLASS_NAME: /* Reference to a named object */
216*4882a593Smuzhiyun
217*4882a593Smuzhiyun /* Dereference the name */
218*4882a593Smuzhiyun
219*4882a593Smuzhiyun if ((stack_desc->reference.node->type ==
220*4882a593Smuzhiyun ACPI_TYPE_DEVICE)
221*4882a593Smuzhiyun || (stack_desc->reference.node->type ==
222*4882a593Smuzhiyun ACPI_TYPE_THERMAL)) {
223*4882a593Smuzhiyun
224*4882a593Smuzhiyun /* These node types do not have 'real' subobjects */
225*4882a593Smuzhiyun
226*4882a593Smuzhiyun *stack_ptr = (void *)stack_desc->reference.node;
227*4882a593Smuzhiyun } else {
228*4882a593Smuzhiyun /* Get the object pointed to by the namespace node */
229*4882a593Smuzhiyun
230*4882a593Smuzhiyun *stack_ptr =
231*4882a593Smuzhiyun (stack_desc->reference.node)->object;
232*4882a593Smuzhiyun acpi_ut_add_reference(*stack_ptr);
233*4882a593Smuzhiyun }
234*4882a593Smuzhiyun
235*4882a593Smuzhiyun acpi_ut_remove_reference(stack_desc);
236*4882a593Smuzhiyun break;
237*4882a593Smuzhiyun
238*4882a593Smuzhiyun default:
239*4882a593Smuzhiyun
240*4882a593Smuzhiyun ACPI_ERROR((AE_INFO,
241*4882a593Smuzhiyun "Unknown Reference type 0x%X in %p",
242*4882a593Smuzhiyun ref_type, stack_desc));
243*4882a593Smuzhiyun status = AE_AML_INTERNAL;
244*4882a593Smuzhiyun break;
245*4882a593Smuzhiyun }
246*4882a593Smuzhiyun break;
247*4882a593Smuzhiyun
248*4882a593Smuzhiyun case ACPI_TYPE_BUFFER:
249*4882a593Smuzhiyun
250*4882a593Smuzhiyun status = acpi_ds_get_buffer_arguments(stack_desc);
251*4882a593Smuzhiyun break;
252*4882a593Smuzhiyun
253*4882a593Smuzhiyun case ACPI_TYPE_PACKAGE:
254*4882a593Smuzhiyun
255*4882a593Smuzhiyun status = acpi_ds_get_package_arguments(stack_desc);
256*4882a593Smuzhiyun break;
257*4882a593Smuzhiyun
258*4882a593Smuzhiyun case ACPI_TYPE_BUFFER_FIELD:
259*4882a593Smuzhiyun case ACPI_TYPE_LOCAL_REGION_FIELD:
260*4882a593Smuzhiyun case ACPI_TYPE_LOCAL_BANK_FIELD:
261*4882a593Smuzhiyun case ACPI_TYPE_LOCAL_INDEX_FIELD:
262*4882a593Smuzhiyun
263*4882a593Smuzhiyun ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
264*4882a593Smuzhiyun "FieldRead SourceDesc=%p Type=%X\n",
265*4882a593Smuzhiyun stack_desc, stack_desc->common.type));
266*4882a593Smuzhiyun
267*4882a593Smuzhiyun status =
268*4882a593Smuzhiyun acpi_ex_read_data_from_field(walk_state, stack_desc,
269*4882a593Smuzhiyun &obj_desc);
270*4882a593Smuzhiyun
271*4882a593Smuzhiyun /* Remove a reference to the original operand, then override */
272*4882a593Smuzhiyun
273*4882a593Smuzhiyun acpi_ut_remove_reference(*stack_ptr);
274*4882a593Smuzhiyun *stack_ptr = (void *)obj_desc;
275*4882a593Smuzhiyun break;
276*4882a593Smuzhiyun
277*4882a593Smuzhiyun default:
278*4882a593Smuzhiyun
279*4882a593Smuzhiyun break;
280*4882a593Smuzhiyun }
281*4882a593Smuzhiyun
282*4882a593Smuzhiyun return_ACPI_STATUS(status);
283*4882a593Smuzhiyun }
284*4882a593Smuzhiyun
285*4882a593Smuzhiyun /*******************************************************************************
286*4882a593Smuzhiyun *
287*4882a593Smuzhiyun * FUNCTION: acpi_ex_resolve_multiple
288*4882a593Smuzhiyun *
289*4882a593Smuzhiyun * PARAMETERS: walk_state - Current state (contains AML opcode)
290*4882a593Smuzhiyun * operand - Starting point for resolution
291*4882a593Smuzhiyun * return_type - Where the object type is returned
292*4882a593Smuzhiyun * return_desc - Where the resolved object is returned
293*4882a593Smuzhiyun *
294*4882a593Smuzhiyun * RETURN: Status
295*4882a593Smuzhiyun *
296*4882a593Smuzhiyun * DESCRIPTION: Return the base object and type. Traverse a reference list if
297*4882a593Smuzhiyun * necessary to get to the base object.
298*4882a593Smuzhiyun *
299*4882a593Smuzhiyun ******************************************************************************/
300*4882a593Smuzhiyun
301*4882a593Smuzhiyun acpi_status
acpi_ex_resolve_multiple(struct acpi_walk_state * walk_state,union acpi_operand_object * operand,acpi_object_type * return_type,union acpi_operand_object ** return_desc)302*4882a593Smuzhiyun acpi_ex_resolve_multiple(struct acpi_walk_state *walk_state,
303*4882a593Smuzhiyun union acpi_operand_object *operand,
304*4882a593Smuzhiyun acpi_object_type *return_type,
305*4882a593Smuzhiyun union acpi_operand_object **return_desc)
306*4882a593Smuzhiyun {
307*4882a593Smuzhiyun union acpi_operand_object *obj_desc = ACPI_CAST_PTR(void, operand);
308*4882a593Smuzhiyun struct acpi_namespace_node *node =
309*4882a593Smuzhiyun ACPI_CAST_PTR(struct acpi_namespace_node, operand);
310*4882a593Smuzhiyun acpi_object_type type;
311*4882a593Smuzhiyun acpi_status status;
312*4882a593Smuzhiyun
313*4882a593Smuzhiyun ACPI_FUNCTION_TRACE(acpi_ex_resolve_multiple);
314*4882a593Smuzhiyun
315*4882a593Smuzhiyun /* Operand can be either a namespace node or an operand descriptor */
316*4882a593Smuzhiyun
317*4882a593Smuzhiyun switch (ACPI_GET_DESCRIPTOR_TYPE(obj_desc)) {
318*4882a593Smuzhiyun case ACPI_DESC_TYPE_OPERAND:
319*4882a593Smuzhiyun
320*4882a593Smuzhiyun type = obj_desc->common.type;
321*4882a593Smuzhiyun break;
322*4882a593Smuzhiyun
323*4882a593Smuzhiyun case ACPI_DESC_TYPE_NAMED:
324*4882a593Smuzhiyun
325*4882a593Smuzhiyun type = ((struct acpi_namespace_node *)obj_desc)->type;
326*4882a593Smuzhiyun obj_desc = acpi_ns_get_attached_object(node);
327*4882a593Smuzhiyun
328*4882a593Smuzhiyun /* If we had an Alias node, use the attached object for type info */
329*4882a593Smuzhiyun
330*4882a593Smuzhiyun if (type == ACPI_TYPE_LOCAL_ALIAS) {
331*4882a593Smuzhiyun type = ((struct acpi_namespace_node *)obj_desc)->type;
332*4882a593Smuzhiyun obj_desc = acpi_ns_get_attached_object((struct
333*4882a593Smuzhiyun acpi_namespace_node
334*4882a593Smuzhiyun *)obj_desc);
335*4882a593Smuzhiyun }
336*4882a593Smuzhiyun
337*4882a593Smuzhiyun switch (type) {
338*4882a593Smuzhiyun case ACPI_TYPE_DEVICE:
339*4882a593Smuzhiyun case ACPI_TYPE_THERMAL:
340*4882a593Smuzhiyun
341*4882a593Smuzhiyun /* These types have no attached subobject */
342*4882a593Smuzhiyun break;
343*4882a593Smuzhiyun
344*4882a593Smuzhiyun default:
345*4882a593Smuzhiyun
346*4882a593Smuzhiyun /* All other types require a subobject */
347*4882a593Smuzhiyun
348*4882a593Smuzhiyun if (!obj_desc) {
349*4882a593Smuzhiyun ACPI_ERROR((AE_INFO,
350*4882a593Smuzhiyun "[%4.4s] Node is unresolved or uninitialized",
351*4882a593Smuzhiyun acpi_ut_get_node_name(node)));
352*4882a593Smuzhiyun return_ACPI_STATUS(AE_AML_UNINITIALIZED_NODE);
353*4882a593Smuzhiyun }
354*4882a593Smuzhiyun break;
355*4882a593Smuzhiyun }
356*4882a593Smuzhiyun break;
357*4882a593Smuzhiyun
358*4882a593Smuzhiyun default:
359*4882a593Smuzhiyun return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
360*4882a593Smuzhiyun }
361*4882a593Smuzhiyun
362*4882a593Smuzhiyun /* If type is anything other than a reference, we are done */
363*4882a593Smuzhiyun
364*4882a593Smuzhiyun if (type != ACPI_TYPE_LOCAL_REFERENCE) {
365*4882a593Smuzhiyun goto exit;
366*4882a593Smuzhiyun }
367*4882a593Smuzhiyun
368*4882a593Smuzhiyun /*
369*4882a593Smuzhiyun * For reference objects created via the ref_of, Index, or Load/load_table
370*4882a593Smuzhiyun * operators, we need to get to the base object (as per the ACPI
371*4882a593Smuzhiyun * specification of the object_type and size_of operators). This means
372*4882a593Smuzhiyun * traversing the list of possibly many nested references.
373*4882a593Smuzhiyun */
374*4882a593Smuzhiyun while (obj_desc->common.type == ACPI_TYPE_LOCAL_REFERENCE) {
375*4882a593Smuzhiyun switch (obj_desc->reference.class) {
376*4882a593Smuzhiyun case ACPI_REFCLASS_REFOF:
377*4882a593Smuzhiyun case ACPI_REFCLASS_NAME:
378*4882a593Smuzhiyun
379*4882a593Smuzhiyun /* Dereference the reference pointer */
380*4882a593Smuzhiyun
381*4882a593Smuzhiyun if (obj_desc->reference.class == ACPI_REFCLASS_REFOF) {
382*4882a593Smuzhiyun node = obj_desc->reference.object;
383*4882a593Smuzhiyun } else { /* AML_INT_NAMEPATH_OP */
384*4882a593Smuzhiyun
385*4882a593Smuzhiyun node = obj_desc->reference.node;
386*4882a593Smuzhiyun }
387*4882a593Smuzhiyun
388*4882a593Smuzhiyun /* All "References" point to a NS node */
389*4882a593Smuzhiyun
390*4882a593Smuzhiyun if (ACPI_GET_DESCRIPTOR_TYPE(node) !=
391*4882a593Smuzhiyun ACPI_DESC_TYPE_NAMED) {
392*4882a593Smuzhiyun ACPI_ERROR((AE_INFO,
393*4882a593Smuzhiyun "Not a namespace node %p [%s]",
394*4882a593Smuzhiyun node,
395*4882a593Smuzhiyun acpi_ut_get_descriptor_name(node)));
396*4882a593Smuzhiyun return_ACPI_STATUS(AE_AML_INTERNAL);
397*4882a593Smuzhiyun }
398*4882a593Smuzhiyun
399*4882a593Smuzhiyun /* Get the attached object */
400*4882a593Smuzhiyun
401*4882a593Smuzhiyun obj_desc = acpi_ns_get_attached_object(node);
402*4882a593Smuzhiyun if (!obj_desc) {
403*4882a593Smuzhiyun
404*4882a593Smuzhiyun /* No object, use the NS node type */
405*4882a593Smuzhiyun
406*4882a593Smuzhiyun type = acpi_ns_get_type(node);
407*4882a593Smuzhiyun goto exit;
408*4882a593Smuzhiyun }
409*4882a593Smuzhiyun
410*4882a593Smuzhiyun /* Check for circular references */
411*4882a593Smuzhiyun
412*4882a593Smuzhiyun if (obj_desc == operand) {
413*4882a593Smuzhiyun return_ACPI_STATUS(AE_AML_CIRCULAR_REFERENCE);
414*4882a593Smuzhiyun }
415*4882a593Smuzhiyun break;
416*4882a593Smuzhiyun
417*4882a593Smuzhiyun case ACPI_REFCLASS_INDEX:
418*4882a593Smuzhiyun
419*4882a593Smuzhiyun /* Get the type of this reference (index into another object) */
420*4882a593Smuzhiyun
421*4882a593Smuzhiyun type = obj_desc->reference.target_type;
422*4882a593Smuzhiyun if (type != ACPI_TYPE_PACKAGE) {
423*4882a593Smuzhiyun goto exit;
424*4882a593Smuzhiyun }
425*4882a593Smuzhiyun
426*4882a593Smuzhiyun /*
427*4882a593Smuzhiyun * The main object is a package, we want to get the type
428*4882a593Smuzhiyun * of the individual package element that is referenced by
429*4882a593Smuzhiyun * the index.
430*4882a593Smuzhiyun *
431*4882a593Smuzhiyun * This could of course in turn be another reference object.
432*4882a593Smuzhiyun */
433*4882a593Smuzhiyun obj_desc = *(obj_desc->reference.where);
434*4882a593Smuzhiyun if (!obj_desc) {
435*4882a593Smuzhiyun
436*4882a593Smuzhiyun /* NULL package elements are allowed */
437*4882a593Smuzhiyun
438*4882a593Smuzhiyun type = 0; /* Uninitialized */
439*4882a593Smuzhiyun goto exit;
440*4882a593Smuzhiyun }
441*4882a593Smuzhiyun break;
442*4882a593Smuzhiyun
443*4882a593Smuzhiyun case ACPI_REFCLASS_TABLE:
444*4882a593Smuzhiyun
445*4882a593Smuzhiyun type = ACPI_TYPE_DDB_HANDLE;
446*4882a593Smuzhiyun goto exit;
447*4882a593Smuzhiyun
448*4882a593Smuzhiyun case ACPI_REFCLASS_LOCAL:
449*4882a593Smuzhiyun case ACPI_REFCLASS_ARG:
450*4882a593Smuzhiyun
451*4882a593Smuzhiyun if (return_desc) {
452*4882a593Smuzhiyun status =
453*4882a593Smuzhiyun acpi_ds_method_data_get_value(obj_desc->
454*4882a593Smuzhiyun reference.
455*4882a593Smuzhiyun class,
456*4882a593Smuzhiyun obj_desc->
457*4882a593Smuzhiyun reference.
458*4882a593Smuzhiyun value,
459*4882a593Smuzhiyun walk_state,
460*4882a593Smuzhiyun &obj_desc);
461*4882a593Smuzhiyun if (ACPI_FAILURE(status)) {
462*4882a593Smuzhiyun return_ACPI_STATUS(status);
463*4882a593Smuzhiyun }
464*4882a593Smuzhiyun acpi_ut_remove_reference(obj_desc);
465*4882a593Smuzhiyun } else {
466*4882a593Smuzhiyun status =
467*4882a593Smuzhiyun acpi_ds_method_data_get_node(obj_desc->
468*4882a593Smuzhiyun reference.
469*4882a593Smuzhiyun class,
470*4882a593Smuzhiyun obj_desc->
471*4882a593Smuzhiyun reference.
472*4882a593Smuzhiyun value,
473*4882a593Smuzhiyun walk_state,
474*4882a593Smuzhiyun &node);
475*4882a593Smuzhiyun if (ACPI_FAILURE(status)) {
476*4882a593Smuzhiyun return_ACPI_STATUS(status);
477*4882a593Smuzhiyun }
478*4882a593Smuzhiyun
479*4882a593Smuzhiyun obj_desc = acpi_ns_get_attached_object(node);
480*4882a593Smuzhiyun if (!obj_desc) {
481*4882a593Smuzhiyun type = ACPI_TYPE_ANY;
482*4882a593Smuzhiyun goto exit;
483*4882a593Smuzhiyun }
484*4882a593Smuzhiyun }
485*4882a593Smuzhiyun break;
486*4882a593Smuzhiyun
487*4882a593Smuzhiyun case ACPI_REFCLASS_DEBUG:
488*4882a593Smuzhiyun
489*4882a593Smuzhiyun /* The Debug Object is of type "DebugObject" */
490*4882a593Smuzhiyun
491*4882a593Smuzhiyun type = ACPI_TYPE_DEBUG_OBJECT;
492*4882a593Smuzhiyun goto exit;
493*4882a593Smuzhiyun
494*4882a593Smuzhiyun default:
495*4882a593Smuzhiyun
496*4882a593Smuzhiyun ACPI_ERROR((AE_INFO,
497*4882a593Smuzhiyun "Unknown Reference Class 0x%2.2X",
498*4882a593Smuzhiyun obj_desc->reference.class));
499*4882a593Smuzhiyun return_ACPI_STATUS(AE_AML_INTERNAL);
500*4882a593Smuzhiyun }
501*4882a593Smuzhiyun }
502*4882a593Smuzhiyun
503*4882a593Smuzhiyun /*
504*4882a593Smuzhiyun * Now we are guaranteed to have an object that has not been created
505*4882a593Smuzhiyun * via the ref_of or Index operators.
506*4882a593Smuzhiyun */
507*4882a593Smuzhiyun type = obj_desc->common.type;
508*4882a593Smuzhiyun
509*4882a593Smuzhiyun exit:
510*4882a593Smuzhiyun /* Convert internal types to external types */
511*4882a593Smuzhiyun
512*4882a593Smuzhiyun switch (type) {
513*4882a593Smuzhiyun case ACPI_TYPE_LOCAL_REGION_FIELD:
514*4882a593Smuzhiyun case ACPI_TYPE_LOCAL_BANK_FIELD:
515*4882a593Smuzhiyun case ACPI_TYPE_LOCAL_INDEX_FIELD:
516*4882a593Smuzhiyun
517*4882a593Smuzhiyun type = ACPI_TYPE_FIELD_UNIT;
518*4882a593Smuzhiyun break;
519*4882a593Smuzhiyun
520*4882a593Smuzhiyun case ACPI_TYPE_LOCAL_SCOPE:
521*4882a593Smuzhiyun
522*4882a593Smuzhiyun /* Per ACPI Specification, Scope is untyped */
523*4882a593Smuzhiyun
524*4882a593Smuzhiyun type = ACPI_TYPE_ANY;
525*4882a593Smuzhiyun break;
526*4882a593Smuzhiyun
527*4882a593Smuzhiyun default:
528*4882a593Smuzhiyun
529*4882a593Smuzhiyun /* No change to Type required */
530*4882a593Smuzhiyun
531*4882a593Smuzhiyun break;
532*4882a593Smuzhiyun }
533*4882a593Smuzhiyun
534*4882a593Smuzhiyun *return_type = type;
535*4882a593Smuzhiyun if (return_desc) {
536*4882a593Smuzhiyun *return_desc = obj_desc;
537*4882a593Smuzhiyun }
538*4882a593Smuzhiyun return_ACPI_STATUS(AE_OK);
539*4882a593Smuzhiyun }
540