195857638SErik Schmauss // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
295b482a8SLen Brown /******************************************************************************
395b482a8SLen Brown *
495b482a8SLen Brown * Module Name: exresolv - AML Interpreter object resolution
595b482a8SLen Brown *
6*612c2932SBob Moore * Copyright (C) 2000 - 2023, Intel Corp.
795b482a8SLen Brown *
895857638SErik Schmauss *****************************************************************************/
995b482a8SLen Brown
1095b482a8SLen Brown #include <acpi/acpi.h>
11e2f7a777SLen Brown #include "accommon.h"
12e2f7a777SLen Brown #include "amlcode.h"
13e2f7a777SLen Brown #include "acdispat.h"
14e2f7a777SLen Brown #include "acinterp.h"
15e2f7a777SLen Brown #include "acnamesp.h"
1695b482a8SLen Brown
1795b482a8SLen Brown #define _COMPONENT ACPI_EXECUTER
1895b482a8SLen Brown ACPI_MODULE_NAME("exresolv")
1995b482a8SLen Brown
2095b482a8SLen Brown /* Local prototypes */
2195b482a8SLen Brown static acpi_status
2295b482a8SLen Brown acpi_ex_resolve_object_to_value(union acpi_operand_object **stack_ptr,
2395b482a8SLen Brown struct acpi_walk_state *walk_state);
2495b482a8SLen Brown
2595b482a8SLen Brown /*******************************************************************************
2695b482a8SLen Brown *
2795b482a8SLen Brown * FUNCTION: acpi_ex_resolve_to_value
2895b482a8SLen Brown *
2995b482a8SLen Brown * PARAMETERS: **stack_ptr - Points to entry on obj_stack, which can
3095b482a8SLen Brown * be either an (union acpi_operand_object *)
3195b482a8SLen Brown * or an acpi_handle.
3295b482a8SLen Brown * walk_state - Current method state
3395b482a8SLen Brown *
3495b482a8SLen Brown * RETURN: Status
3595b482a8SLen Brown *
3695b482a8SLen Brown * DESCRIPTION: Convert Reference objects to values
3795b482a8SLen Brown *
3895b482a8SLen Brown ******************************************************************************/
3995b482a8SLen Brown
4095b482a8SLen Brown acpi_status
acpi_ex_resolve_to_value(union acpi_operand_object ** stack_ptr,struct acpi_walk_state * walk_state)4195b482a8SLen Brown acpi_ex_resolve_to_value(union acpi_operand_object **stack_ptr,
4295b482a8SLen Brown struct acpi_walk_state *walk_state)
4395b482a8SLen Brown {
4495b482a8SLen Brown acpi_status status;
4595b482a8SLen Brown
4695b482a8SLen Brown ACPI_FUNCTION_TRACE_PTR(ex_resolve_to_value, stack_ptr);
4795b482a8SLen Brown
4895b482a8SLen Brown if (!stack_ptr || !*stack_ptr) {
4995b482a8SLen Brown ACPI_ERROR((AE_INFO, "Internal - null pointer"));
5095b482a8SLen Brown return_ACPI_STATUS(AE_AML_NO_OPERAND);
5195b482a8SLen Brown }
5295b482a8SLen Brown
5395b482a8SLen Brown /*
5495b482a8SLen Brown * The entity pointed to by the stack_ptr can be either
5595b482a8SLen Brown * 1) A valid union acpi_operand_object, or
5695b482a8SLen Brown * 2) A struct acpi_namespace_node (named_obj)
5795b482a8SLen Brown */
5895b482a8SLen Brown if (ACPI_GET_DESCRIPTOR_TYPE(*stack_ptr) == ACPI_DESC_TYPE_OPERAND) {
5995b482a8SLen Brown status = acpi_ex_resolve_object_to_value(stack_ptr, walk_state);
6095b482a8SLen Brown if (ACPI_FAILURE(status)) {
6195b482a8SLen Brown return_ACPI_STATUS(status);
6295b482a8SLen Brown }
6395b482a8SLen Brown
6495b482a8SLen Brown if (!*stack_ptr) {
6595b482a8SLen Brown ACPI_ERROR((AE_INFO, "Internal - null pointer"));
6695b482a8SLen Brown return_ACPI_STATUS(AE_AML_NO_OPERAND);
6795b482a8SLen Brown }
6895b482a8SLen Brown }
6995b482a8SLen Brown
7095b482a8SLen Brown /*
7195b482a8SLen Brown * Object on the stack may have changed if acpi_ex_resolve_object_to_value()
7295b482a8SLen Brown * was called (i.e., we can't use an _else_ here.)
7395b482a8SLen Brown */
7495b482a8SLen Brown if (ACPI_GET_DESCRIPTOR_TYPE(*stack_ptr) == ACPI_DESC_TYPE_NAMED) {
7595b482a8SLen Brown status =
7695b482a8SLen Brown acpi_ex_resolve_node_to_value(ACPI_CAST_INDIRECT_PTR
7795b482a8SLen Brown (struct acpi_namespace_node,
7895b482a8SLen Brown stack_ptr), walk_state);
7995b482a8SLen Brown if (ACPI_FAILURE(status)) {
8095b482a8SLen Brown return_ACPI_STATUS(status);
8195b482a8SLen Brown }
8295b482a8SLen Brown }
8395b482a8SLen Brown
8495b482a8SLen Brown ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Resolved object %p\n", *stack_ptr));
8595b482a8SLen Brown return_ACPI_STATUS(AE_OK);
8695b482a8SLen Brown }
8795b482a8SLen Brown
8895b482a8SLen Brown /*******************************************************************************
8995b482a8SLen Brown *
9095b482a8SLen Brown * FUNCTION: acpi_ex_resolve_object_to_value
9195b482a8SLen Brown *
9295b482a8SLen Brown * PARAMETERS: stack_ptr - Pointer to an internal object
9395b482a8SLen Brown * walk_state - Current method state
9495b482a8SLen Brown *
9595b482a8SLen Brown * RETURN: Status
9695b482a8SLen Brown *
9795b482a8SLen Brown * DESCRIPTION: Retrieve the value from an internal object. The Reference type
9895b482a8SLen Brown * uses the associated AML opcode to determine the value.
9995b482a8SLen Brown *
10095b482a8SLen Brown ******************************************************************************/
10195b482a8SLen Brown
10295b482a8SLen Brown static acpi_status
acpi_ex_resolve_object_to_value(union acpi_operand_object ** stack_ptr,struct acpi_walk_state * walk_state)10395b482a8SLen Brown acpi_ex_resolve_object_to_value(union acpi_operand_object **stack_ptr,
10495b482a8SLen Brown struct acpi_walk_state *walk_state)
10595b482a8SLen Brown {
10695b482a8SLen Brown acpi_status status = AE_OK;
10795b482a8SLen Brown union acpi_operand_object *stack_desc;
10895b482a8SLen Brown union acpi_operand_object *obj_desc = NULL;
10995b482a8SLen Brown u8 ref_type;
11095b482a8SLen Brown
11195b482a8SLen Brown ACPI_FUNCTION_TRACE(ex_resolve_object_to_value);
11295b482a8SLen Brown
11395b482a8SLen Brown stack_desc = *stack_ptr;
11495b482a8SLen Brown
115cf48958eSBob Moore /* This is an object of type union acpi_operand_object */
11695b482a8SLen Brown
1173371c19cSBob Moore switch (stack_desc->common.type) {
11895b482a8SLen Brown case ACPI_TYPE_LOCAL_REFERENCE:
11995b482a8SLen Brown
12095b482a8SLen Brown ref_type = stack_desc->reference.class;
12195b482a8SLen Brown
12295b482a8SLen Brown switch (ref_type) {
12395b482a8SLen Brown case ACPI_REFCLASS_LOCAL:
12495b482a8SLen Brown case ACPI_REFCLASS_ARG:
12595b482a8SLen Brown /*
12695b482a8SLen Brown * Get the local from the method's state info
12795b482a8SLen Brown * Note: this increments the local's object reference count
12895b482a8SLen Brown */
12995b482a8SLen Brown status = acpi_ds_method_data_get_value(ref_type,
13095b482a8SLen Brown stack_desc->
13195b482a8SLen Brown reference.value,
13295b482a8SLen Brown walk_state,
13395b482a8SLen Brown &obj_desc);
13495b482a8SLen Brown if (ACPI_FAILURE(status)) {
13595b482a8SLen Brown return_ACPI_STATUS(status);
13695b482a8SLen Brown }
13795b482a8SLen Brown
13895b482a8SLen Brown ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
13995b482a8SLen Brown "[Arg/Local %X] ValueObj is %p\n",
14095b482a8SLen Brown stack_desc->reference.value,
14195b482a8SLen Brown obj_desc));
14295b482a8SLen Brown
14395b482a8SLen Brown /*
14495b482a8SLen Brown * Now we can delete the original Reference Object and
14595b482a8SLen Brown * replace it with the resolved value
14695b482a8SLen Brown */
14795b482a8SLen Brown acpi_ut_remove_reference(stack_desc);
14895b482a8SLen Brown *stack_ptr = obj_desc;
14995b482a8SLen Brown break;
15095b482a8SLen Brown
15195b482a8SLen Brown case ACPI_REFCLASS_INDEX:
15295b482a8SLen Brown
15395b482a8SLen Brown switch (stack_desc->reference.target_type) {
15495b482a8SLen Brown case ACPI_TYPE_BUFFER_FIELD:
15595b482a8SLen Brown
15695b482a8SLen Brown /* Just return - do not dereference */
15795b482a8SLen Brown break;
15895b482a8SLen Brown
15995b482a8SLen Brown case ACPI_TYPE_PACKAGE:
16095b482a8SLen Brown
16195b482a8SLen Brown /* If method call or copy_object - do not dereference */
16295b482a8SLen Brown
16395b482a8SLen Brown if ((walk_state->opcode ==
16495b482a8SLen Brown AML_INT_METHODCALL_OP)
1659ff5a21aSBob Moore || (walk_state->opcode ==
1669ff5a21aSBob Moore AML_COPY_OBJECT_OP)) {
16795b482a8SLen Brown break;
16895b482a8SLen Brown }
16995b482a8SLen Brown
17095b482a8SLen Brown /* Otherwise, dereference the package_index to a package element */
17195b482a8SLen Brown
17295b482a8SLen Brown obj_desc = *stack_desc->reference.where;
17395b482a8SLen Brown if (obj_desc) {
17495b482a8SLen Brown /*
17595b482a8SLen Brown * Valid object descriptor, copy pointer to return value
17695b482a8SLen Brown * (i.e., dereference the package index)
17795b482a8SLen Brown * Delete the ref object, increment the returned object
17895b482a8SLen Brown */
17995b482a8SLen Brown acpi_ut_add_reference(obj_desc);
18095b482a8SLen Brown *stack_ptr = obj_desc;
18195b482a8SLen Brown } else {
18295b482a8SLen Brown /*
18395b482a8SLen Brown * A NULL object descriptor means an uninitialized element of
18495b482a8SLen Brown * the package, can't dereference it
18595b482a8SLen Brown */
18695b482a8SLen Brown ACPI_ERROR((AE_INFO,
1871fad8738SBob Moore "Attempt to dereference an Index to "
1881fad8738SBob Moore "NULL package element Idx=%p",
18995b482a8SLen Brown stack_desc));
19095b482a8SLen Brown status = AE_AML_UNINITIALIZED_ELEMENT;
19195b482a8SLen Brown }
19295b482a8SLen Brown break;
19395b482a8SLen Brown
19495b482a8SLen Brown default:
19595b482a8SLen Brown
19695b482a8SLen Brown /* Invalid reference object */
19795b482a8SLen Brown
19895b482a8SLen Brown ACPI_ERROR((AE_INFO,
199f6a22b0bSBob Moore "Unknown TargetType 0x%X in Index/Reference object %p",
20095b482a8SLen Brown stack_desc->reference.target_type,
20195b482a8SLen Brown stack_desc));
20295b482a8SLen Brown status = AE_AML_INTERNAL;
20395b482a8SLen Brown break;
20495b482a8SLen Brown }
20595b482a8SLen Brown break;
20695b482a8SLen Brown
20795b482a8SLen Brown case ACPI_REFCLASS_REFOF:
20895b482a8SLen Brown case ACPI_REFCLASS_DEBUG:
20995b482a8SLen Brown case ACPI_REFCLASS_TABLE:
21095b482a8SLen Brown
21195b482a8SLen Brown /* Just leave the object as-is, do not dereference */
21295b482a8SLen Brown
21395b482a8SLen Brown break;
21495b482a8SLen Brown
21595b482a8SLen Brown case ACPI_REFCLASS_NAME: /* Reference to a named object */
21695b482a8SLen Brown
21795b482a8SLen Brown /* Dereference the name */
21895b482a8SLen Brown
21995b482a8SLen Brown if ((stack_desc->reference.node->type ==
22095b482a8SLen Brown ACPI_TYPE_DEVICE)
22195b482a8SLen Brown || (stack_desc->reference.node->type ==
22295b482a8SLen Brown ACPI_TYPE_THERMAL)) {
22395b482a8SLen Brown
22495b482a8SLen Brown /* These node types do not have 'real' subobjects */
22595b482a8SLen Brown
22695b482a8SLen Brown *stack_ptr = (void *)stack_desc->reference.node;
22795b482a8SLen Brown } else {
22895b482a8SLen Brown /* Get the object pointed to by the namespace node */
22995b482a8SLen Brown
23095b482a8SLen Brown *stack_ptr =
23195b482a8SLen Brown (stack_desc->reference.node)->object;
23295b482a8SLen Brown acpi_ut_add_reference(*stack_ptr);
23395b482a8SLen Brown }
23495b482a8SLen Brown
23595b482a8SLen Brown acpi_ut_remove_reference(stack_desc);
23695b482a8SLen Brown break;
23795b482a8SLen Brown
23895b482a8SLen Brown default:
23995b482a8SLen Brown
24095b482a8SLen Brown ACPI_ERROR((AE_INFO,
241f6a22b0bSBob Moore "Unknown Reference type 0x%X in %p",
242f6a22b0bSBob Moore ref_type, stack_desc));
24395b482a8SLen Brown status = AE_AML_INTERNAL;
24495b482a8SLen Brown break;
24595b482a8SLen Brown }
24695b482a8SLen Brown break;
24795b482a8SLen Brown
24895b482a8SLen Brown case ACPI_TYPE_BUFFER:
24995b482a8SLen Brown
25095b482a8SLen Brown status = acpi_ds_get_buffer_arguments(stack_desc);
25195b482a8SLen Brown break;
25295b482a8SLen Brown
25395b482a8SLen Brown case ACPI_TYPE_PACKAGE:
25495b482a8SLen Brown
25595b482a8SLen Brown status = acpi_ds_get_package_arguments(stack_desc);
25695b482a8SLen Brown break;
25795b482a8SLen Brown
25895b482a8SLen Brown case ACPI_TYPE_BUFFER_FIELD:
25995b482a8SLen Brown case ACPI_TYPE_LOCAL_REGION_FIELD:
26095b482a8SLen Brown case ACPI_TYPE_LOCAL_BANK_FIELD:
26195b482a8SLen Brown case ACPI_TYPE_LOCAL_INDEX_FIELD:
26295b482a8SLen Brown
26395b482a8SLen Brown ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
26495b482a8SLen Brown "FieldRead SourceDesc=%p Type=%X\n",
2653371c19cSBob Moore stack_desc, stack_desc->common.type));
26695b482a8SLen Brown
26795b482a8SLen Brown status =
26895b482a8SLen Brown acpi_ex_read_data_from_field(walk_state, stack_desc,
26995b482a8SLen Brown &obj_desc);
27095b482a8SLen Brown
27195b482a8SLen Brown /* Remove a reference to the original operand, then override */
27295b482a8SLen Brown
27395b482a8SLen Brown acpi_ut_remove_reference(*stack_ptr);
27495b482a8SLen Brown *stack_ptr = (void *)obj_desc;
27595b482a8SLen Brown break;
27695b482a8SLen Brown
27795b482a8SLen Brown default:
2781d1ea1b7SChao Guan
27995b482a8SLen Brown break;
28095b482a8SLen Brown }
28195b482a8SLen Brown
28295b482a8SLen Brown return_ACPI_STATUS(status);
28395b482a8SLen Brown }
28495b482a8SLen Brown
28595b482a8SLen Brown /*******************************************************************************
28695b482a8SLen Brown *
28795b482a8SLen Brown * FUNCTION: acpi_ex_resolve_multiple
28895b482a8SLen Brown *
28995b482a8SLen Brown * PARAMETERS: walk_state - Current state (contains AML opcode)
290ba494beeSBob Moore * operand - Starting point for resolution
29195b482a8SLen Brown * return_type - Where the object type is returned
29295b482a8SLen Brown * return_desc - Where the resolved object is returned
29395b482a8SLen Brown *
29495b482a8SLen Brown * RETURN: Status
29595b482a8SLen Brown *
29695b482a8SLen Brown * DESCRIPTION: Return the base object and type. Traverse a reference list if
29795b482a8SLen Brown * necessary to get to the base object.
29895b482a8SLen Brown *
29995b482a8SLen Brown ******************************************************************************/
30095b482a8SLen Brown
30195b482a8SLen Brown 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)30295b482a8SLen Brown acpi_ex_resolve_multiple(struct acpi_walk_state *walk_state,
30395b482a8SLen Brown union acpi_operand_object *operand,
30495b482a8SLen Brown acpi_object_type *return_type,
30595b482a8SLen Brown union acpi_operand_object **return_desc)
30695b482a8SLen Brown {
3074712f71bSBob Moore union acpi_operand_object *obj_desc = ACPI_CAST_PTR(void, operand);
3084712f71bSBob Moore struct acpi_namespace_node *node =
3094712f71bSBob Moore ACPI_CAST_PTR(struct acpi_namespace_node, operand);
31095b482a8SLen Brown acpi_object_type type;
31195b482a8SLen Brown acpi_status status;
31295b482a8SLen Brown
31395b482a8SLen Brown ACPI_FUNCTION_TRACE(acpi_ex_resolve_multiple);
31495b482a8SLen Brown
31595b482a8SLen Brown /* Operand can be either a namespace node or an operand descriptor */
31695b482a8SLen Brown
31795b482a8SLen Brown switch (ACPI_GET_DESCRIPTOR_TYPE(obj_desc)) {
31895b482a8SLen Brown case ACPI_DESC_TYPE_OPERAND:
3191d1ea1b7SChao Guan
32095b482a8SLen Brown type = obj_desc->common.type;
32195b482a8SLen Brown break;
32295b482a8SLen Brown
32395b482a8SLen Brown case ACPI_DESC_TYPE_NAMED:
3241d1ea1b7SChao Guan
32595b482a8SLen Brown type = ((struct acpi_namespace_node *)obj_desc)->type;
3264712f71bSBob Moore obj_desc = acpi_ns_get_attached_object(node);
32795b482a8SLen Brown
32895b482a8SLen Brown /* If we had an Alias node, use the attached object for type info */
32995b482a8SLen Brown
33095b482a8SLen Brown if (type == ACPI_TYPE_LOCAL_ALIAS) {
33195b482a8SLen Brown type = ((struct acpi_namespace_node *)obj_desc)->type;
3321fad8738SBob Moore obj_desc = acpi_ns_get_attached_object((struct
3331fad8738SBob Moore acpi_namespace_node
3341fad8738SBob Moore *)obj_desc);
33595b482a8SLen Brown }
3364712f71bSBob Moore
3371d6e9cfaSBob Moore switch (type) {
3381d6e9cfaSBob Moore case ACPI_TYPE_DEVICE:
3391d6e9cfaSBob Moore case ACPI_TYPE_THERMAL:
3401d6e9cfaSBob Moore
3411d6e9cfaSBob Moore /* These types have no attached subobject */
3421d6e9cfaSBob Moore break;
3431d6e9cfaSBob Moore
3441d6e9cfaSBob Moore default:
3451d6e9cfaSBob Moore
3461d6e9cfaSBob Moore /* All other types require a subobject */
3471d6e9cfaSBob Moore
3484712f71bSBob Moore if (!obj_desc) {
3494712f71bSBob Moore ACPI_ERROR((AE_INFO,
3504712f71bSBob Moore "[%4.4s] Node is unresolved or uninitialized",
3514712f71bSBob Moore acpi_ut_get_node_name(node)));
3524712f71bSBob Moore return_ACPI_STATUS(AE_AML_UNINITIALIZED_NODE);
3534712f71bSBob Moore }
35495b482a8SLen Brown break;
3551d6e9cfaSBob Moore }
3561d6e9cfaSBob Moore break;
35795b482a8SLen Brown
35895b482a8SLen Brown default:
35995b482a8SLen Brown return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
36095b482a8SLen Brown }
36195b482a8SLen Brown
36295b482a8SLen Brown /* If type is anything other than a reference, we are done */
36395b482a8SLen Brown
36495b482a8SLen Brown if (type != ACPI_TYPE_LOCAL_REFERENCE) {
36595b482a8SLen Brown goto exit;
36695b482a8SLen Brown }
36795b482a8SLen Brown
36895b482a8SLen Brown /*
36995b482a8SLen Brown * For reference objects created via the ref_of, Index, or Load/load_table
37095b482a8SLen Brown * operators, we need to get to the base object (as per the ACPI
37195b482a8SLen Brown * specification of the object_type and size_of operators). This means
37295b482a8SLen Brown * traversing the list of possibly many nested references.
37395b482a8SLen Brown */
3743371c19cSBob Moore while (obj_desc->common.type == ACPI_TYPE_LOCAL_REFERENCE) {
37595b482a8SLen Brown switch (obj_desc->reference.class) {
37695b482a8SLen Brown case ACPI_REFCLASS_REFOF:
37795b482a8SLen Brown case ACPI_REFCLASS_NAME:
37895b482a8SLen Brown
37995b482a8SLen Brown /* Dereference the reference pointer */
38095b482a8SLen Brown
38195b482a8SLen Brown if (obj_desc->reference.class == ACPI_REFCLASS_REFOF) {
38295b482a8SLen Brown node = obj_desc->reference.object;
38395b482a8SLen Brown } else { /* AML_INT_NAMEPATH_OP */
38495b482a8SLen Brown
38595b482a8SLen Brown node = obj_desc->reference.node;
38695b482a8SLen Brown }
38795b482a8SLen Brown
38895b482a8SLen Brown /* All "References" point to a NS node */
38995b482a8SLen Brown
39095b482a8SLen Brown if (ACPI_GET_DESCRIPTOR_TYPE(node) !=
39195b482a8SLen Brown ACPI_DESC_TYPE_NAMED) {
392f6a22b0bSBob Moore ACPI_ERROR((AE_INFO,
393f6a22b0bSBob Moore "Not a namespace node %p [%s]",
39495b482a8SLen Brown node,
39595b482a8SLen Brown acpi_ut_get_descriptor_name(node)));
39695b482a8SLen Brown return_ACPI_STATUS(AE_AML_INTERNAL);
39795b482a8SLen Brown }
39895b482a8SLen Brown
39995b482a8SLen Brown /* Get the attached object */
40095b482a8SLen Brown
40195b482a8SLen Brown obj_desc = acpi_ns_get_attached_object(node);
40295b482a8SLen Brown if (!obj_desc) {
40395b482a8SLen Brown
40495b482a8SLen Brown /* No object, use the NS node type */
40595b482a8SLen Brown
40695b482a8SLen Brown type = acpi_ns_get_type(node);
40795b482a8SLen Brown goto exit;
40895b482a8SLen Brown }
40995b482a8SLen Brown
41095b482a8SLen Brown /* Check for circular references */
41195b482a8SLen Brown
41295b482a8SLen Brown if (obj_desc == operand) {
41395b482a8SLen Brown return_ACPI_STATUS(AE_AML_CIRCULAR_REFERENCE);
41495b482a8SLen Brown }
41595b482a8SLen Brown break;
41695b482a8SLen Brown
41795b482a8SLen Brown case ACPI_REFCLASS_INDEX:
41895b482a8SLen Brown
41995b482a8SLen Brown /* Get the type of this reference (index into another object) */
42095b482a8SLen Brown
42195b482a8SLen Brown type = obj_desc->reference.target_type;
42295b482a8SLen Brown if (type != ACPI_TYPE_PACKAGE) {
42395b482a8SLen Brown goto exit;
42495b482a8SLen Brown }
42595b482a8SLen Brown
42695b482a8SLen Brown /*
42795b482a8SLen Brown * The main object is a package, we want to get the type
42895b482a8SLen Brown * of the individual package element that is referenced by
42995b482a8SLen Brown * the index.
43095b482a8SLen Brown *
43195b482a8SLen Brown * This could of course in turn be another reference object.
43295b482a8SLen Brown */
43395b482a8SLen Brown obj_desc = *(obj_desc->reference.where);
43495b482a8SLen Brown if (!obj_desc) {
43595b482a8SLen Brown
43695b482a8SLen Brown /* NULL package elements are allowed */
43795b482a8SLen Brown
43895b482a8SLen Brown type = 0; /* Uninitialized */
43995b482a8SLen Brown goto exit;
44095b482a8SLen Brown }
44195b482a8SLen Brown break;
44295b482a8SLen Brown
44395b482a8SLen Brown case ACPI_REFCLASS_TABLE:
44495b482a8SLen Brown
44595b482a8SLen Brown type = ACPI_TYPE_DDB_HANDLE;
44695b482a8SLen Brown goto exit;
44795b482a8SLen Brown
44895b482a8SLen Brown case ACPI_REFCLASS_LOCAL:
44995b482a8SLen Brown case ACPI_REFCLASS_ARG:
45095b482a8SLen Brown
45195b482a8SLen Brown if (return_desc) {
45295b482a8SLen Brown status =
45395b482a8SLen Brown acpi_ds_method_data_get_value(obj_desc->
45495b482a8SLen Brown reference.
45595b482a8SLen Brown class,
45695b482a8SLen Brown obj_desc->
45795b482a8SLen Brown reference.
45895b482a8SLen Brown value,
45995b482a8SLen Brown walk_state,
46095b482a8SLen Brown &obj_desc);
46195b482a8SLen Brown if (ACPI_FAILURE(status)) {
46295b482a8SLen Brown return_ACPI_STATUS(status);
46395b482a8SLen Brown }
46495b482a8SLen Brown acpi_ut_remove_reference(obj_desc);
46595b482a8SLen Brown } else {
46695b482a8SLen Brown status =
46795b482a8SLen Brown acpi_ds_method_data_get_node(obj_desc->
46895b482a8SLen Brown reference.
46995b482a8SLen Brown class,
47095b482a8SLen Brown obj_desc->
47195b482a8SLen Brown reference.
47295b482a8SLen Brown value,
47395b482a8SLen Brown walk_state,
47495b482a8SLen Brown &node);
47595b482a8SLen Brown if (ACPI_FAILURE(status)) {
47695b482a8SLen Brown return_ACPI_STATUS(status);
47795b482a8SLen Brown }
47895b482a8SLen Brown
47995b482a8SLen Brown obj_desc = acpi_ns_get_attached_object(node);
48095b482a8SLen Brown if (!obj_desc) {
48195b482a8SLen Brown type = ACPI_TYPE_ANY;
48295b482a8SLen Brown goto exit;
48395b482a8SLen Brown }
48495b482a8SLen Brown }
48595b482a8SLen Brown break;
48695b482a8SLen Brown
48795b482a8SLen Brown case ACPI_REFCLASS_DEBUG:
48895b482a8SLen Brown
48995b482a8SLen Brown /* The Debug Object is of type "DebugObject" */
49095b482a8SLen Brown
49195b482a8SLen Brown type = ACPI_TYPE_DEBUG_OBJECT;
49295b482a8SLen Brown goto exit;
49395b482a8SLen Brown
49495b482a8SLen Brown default:
49595b482a8SLen Brown
49695b482a8SLen Brown ACPI_ERROR((AE_INFO,
497f6a22b0bSBob Moore "Unknown Reference Class 0x%2.2X",
49895b482a8SLen Brown obj_desc->reference.class));
49995b482a8SLen Brown return_ACPI_STATUS(AE_AML_INTERNAL);
50095b482a8SLen Brown }
50195b482a8SLen Brown }
50295b482a8SLen Brown
50395b482a8SLen Brown /*
50495b482a8SLen Brown * Now we are guaranteed to have an object that has not been created
50595b482a8SLen Brown * via the ref_of or Index operators.
50695b482a8SLen Brown */
5073371c19cSBob Moore type = obj_desc->common.type;
50895b482a8SLen Brown
50995b482a8SLen Brown exit:
51095b482a8SLen Brown /* Convert internal types to external types */
51195b482a8SLen Brown
51295b482a8SLen Brown switch (type) {
51395b482a8SLen Brown case ACPI_TYPE_LOCAL_REGION_FIELD:
51495b482a8SLen Brown case ACPI_TYPE_LOCAL_BANK_FIELD:
51595b482a8SLen Brown case ACPI_TYPE_LOCAL_INDEX_FIELD:
51695b482a8SLen Brown
51795b482a8SLen Brown type = ACPI_TYPE_FIELD_UNIT;
51895b482a8SLen Brown break;
51995b482a8SLen Brown
52095b482a8SLen Brown case ACPI_TYPE_LOCAL_SCOPE:
52195b482a8SLen Brown
52295b482a8SLen Brown /* Per ACPI Specification, Scope is untyped */
52395b482a8SLen Brown
52495b482a8SLen Brown type = ACPI_TYPE_ANY;
52595b482a8SLen Brown break;
52695b482a8SLen Brown
52795b482a8SLen Brown default:
5281d1ea1b7SChao Guan
52995b482a8SLen Brown /* No change to Type required */
5301d1ea1b7SChao Guan
53195b482a8SLen Brown break;
53295b482a8SLen Brown }
53395b482a8SLen Brown
53495b482a8SLen Brown *return_type = type;
53595b482a8SLen Brown if (return_desc) {
53695b482a8SLen Brown *return_desc = obj_desc;
53795b482a8SLen Brown }
53895b482a8SLen Brown return_ACPI_STATUS(AE_OK);
53995b482a8SLen Brown }
540