162306a36Sopenharmony_ci// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 262306a36Sopenharmony_ci/****************************************************************************** 362306a36Sopenharmony_ci * 462306a36Sopenharmony_ci * Module Name: exresolv - AML Interpreter object resolution 562306a36Sopenharmony_ci * 662306a36Sopenharmony_ci * Copyright (C) 2000 - 2023, Intel Corp. 762306a36Sopenharmony_ci * 862306a36Sopenharmony_ci *****************************************************************************/ 962306a36Sopenharmony_ci 1062306a36Sopenharmony_ci#include <acpi/acpi.h> 1162306a36Sopenharmony_ci#include "accommon.h" 1262306a36Sopenharmony_ci#include "amlcode.h" 1362306a36Sopenharmony_ci#include "acdispat.h" 1462306a36Sopenharmony_ci#include "acinterp.h" 1562306a36Sopenharmony_ci#include "acnamesp.h" 1662306a36Sopenharmony_ci 1762306a36Sopenharmony_ci#define _COMPONENT ACPI_EXECUTER 1862306a36Sopenharmony_ciACPI_MODULE_NAME("exresolv") 1962306a36Sopenharmony_ci 2062306a36Sopenharmony_ci/* Local prototypes */ 2162306a36Sopenharmony_cistatic acpi_status 2262306a36Sopenharmony_ciacpi_ex_resolve_object_to_value(union acpi_operand_object **stack_ptr, 2362306a36Sopenharmony_ci struct acpi_walk_state *walk_state); 2462306a36Sopenharmony_ci 2562306a36Sopenharmony_ci/******************************************************************************* 2662306a36Sopenharmony_ci * 2762306a36Sopenharmony_ci * FUNCTION: acpi_ex_resolve_to_value 2862306a36Sopenharmony_ci * 2962306a36Sopenharmony_ci * PARAMETERS: **stack_ptr - Points to entry on obj_stack, which can 3062306a36Sopenharmony_ci * be either an (union acpi_operand_object *) 3162306a36Sopenharmony_ci * or an acpi_handle. 3262306a36Sopenharmony_ci * walk_state - Current method state 3362306a36Sopenharmony_ci * 3462306a36Sopenharmony_ci * RETURN: Status 3562306a36Sopenharmony_ci * 3662306a36Sopenharmony_ci * DESCRIPTION: Convert Reference objects to values 3762306a36Sopenharmony_ci * 3862306a36Sopenharmony_ci ******************************************************************************/ 3962306a36Sopenharmony_ci 4062306a36Sopenharmony_ciacpi_status 4162306a36Sopenharmony_ciacpi_ex_resolve_to_value(union acpi_operand_object **stack_ptr, 4262306a36Sopenharmony_ci struct acpi_walk_state *walk_state) 4362306a36Sopenharmony_ci{ 4462306a36Sopenharmony_ci acpi_status status; 4562306a36Sopenharmony_ci 4662306a36Sopenharmony_ci ACPI_FUNCTION_TRACE_PTR(ex_resolve_to_value, stack_ptr); 4762306a36Sopenharmony_ci 4862306a36Sopenharmony_ci if (!stack_ptr || !*stack_ptr) { 4962306a36Sopenharmony_ci ACPI_ERROR((AE_INFO, "Internal - null pointer")); 5062306a36Sopenharmony_ci return_ACPI_STATUS(AE_AML_NO_OPERAND); 5162306a36Sopenharmony_ci } 5262306a36Sopenharmony_ci 5362306a36Sopenharmony_ci /* 5462306a36Sopenharmony_ci * The entity pointed to by the stack_ptr can be either 5562306a36Sopenharmony_ci * 1) A valid union acpi_operand_object, or 5662306a36Sopenharmony_ci * 2) A struct acpi_namespace_node (named_obj) 5762306a36Sopenharmony_ci */ 5862306a36Sopenharmony_ci if (ACPI_GET_DESCRIPTOR_TYPE(*stack_ptr) == ACPI_DESC_TYPE_OPERAND) { 5962306a36Sopenharmony_ci status = acpi_ex_resolve_object_to_value(stack_ptr, walk_state); 6062306a36Sopenharmony_ci if (ACPI_FAILURE(status)) { 6162306a36Sopenharmony_ci return_ACPI_STATUS(status); 6262306a36Sopenharmony_ci } 6362306a36Sopenharmony_ci 6462306a36Sopenharmony_ci if (!*stack_ptr) { 6562306a36Sopenharmony_ci ACPI_ERROR((AE_INFO, "Internal - null pointer")); 6662306a36Sopenharmony_ci return_ACPI_STATUS(AE_AML_NO_OPERAND); 6762306a36Sopenharmony_ci } 6862306a36Sopenharmony_ci } 6962306a36Sopenharmony_ci 7062306a36Sopenharmony_ci /* 7162306a36Sopenharmony_ci * Object on the stack may have changed if acpi_ex_resolve_object_to_value() 7262306a36Sopenharmony_ci * was called (i.e., we can't use an _else_ here.) 7362306a36Sopenharmony_ci */ 7462306a36Sopenharmony_ci if (ACPI_GET_DESCRIPTOR_TYPE(*stack_ptr) == ACPI_DESC_TYPE_NAMED) { 7562306a36Sopenharmony_ci status = 7662306a36Sopenharmony_ci acpi_ex_resolve_node_to_value(ACPI_CAST_INDIRECT_PTR 7762306a36Sopenharmony_ci (struct acpi_namespace_node, 7862306a36Sopenharmony_ci stack_ptr), walk_state); 7962306a36Sopenharmony_ci if (ACPI_FAILURE(status)) { 8062306a36Sopenharmony_ci return_ACPI_STATUS(status); 8162306a36Sopenharmony_ci } 8262306a36Sopenharmony_ci } 8362306a36Sopenharmony_ci 8462306a36Sopenharmony_ci ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Resolved object %p\n", *stack_ptr)); 8562306a36Sopenharmony_ci return_ACPI_STATUS(AE_OK); 8662306a36Sopenharmony_ci} 8762306a36Sopenharmony_ci 8862306a36Sopenharmony_ci/******************************************************************************* 8962306a36Sopenharmony_ci * 9062306a36Sopenharmony_ci * FUNCTION: acpi_ex_resolve_object_to_value 9162306a36Sopenharmony_ci * 9262306a36Sopenharmony_ci * PARAMETERS: stack_ptr - Pointer to an internal object 9362306a36Sopenharmony_ci * walk_state - Current method state 9462306a36Sopenharmony_ci * 9562306a36Sopenharmony_ci * RETURN: Status 9662306a36Sopenharmony_ci * 9762306a36Sopenharmony_ci * DESCRIPTION: Retrieve the value from an internal object. The Reference type 9862306a36Sopenharmony_ci * uses the associated AML opcode to determine the value. 9962306a36Sopenharmony_ci * 10062306a36Sopenharmony_ci ******************************************************************************/ 10162306a36Sopenharmony_ci 10262306a36Sopenharmony_cistatic acpi_status 10362306a36Sopenharmony_ciacpi_ex_resolve_object_to_value(union acpi_operand_object **stack_ptr, 10462306a36Sopenharmony_ci struct acpi_walk_state *walk_state) 10562306a36Sopenharmony_ci{ 10662306a36Sopenharmony_ci acpi_status status = AE_OK; 10762306a36Sopenharmony_ci union acpi_operand_object *stack_desc; 10862306a36Sopenharmony_ci union acpi_operand_object *obj_desc = NULL; 10962306a36Sopenharmony_ci u8 ref_type; 11062306a36Sopenharmony_ci 11162306a36Sopenharmony_ci ACPI_FUNCTION_TRACE(ex_resolve_object_to_value); 11262306a36Sopenharmony_ci 11362306a36Sopenharmony_ci stack_desc = *stack_ptr; 11462306a36Sopenharmony_ci 11562306a36Sopenharmony_ci /* This is an object of type union acpi_operand_object */ 11662306a36Sopenharmony_ci 11762306a36Sopenharmony_ci switch (stack_desc->common.type) { 11862306a36Sopenharmony_ci case ACPI_TYPE_LOCAL_REFERENCE: 11962306a36Sopenharmony_ci 12062306a36Sopenharmony_ci ref_type = stack_desc->reference.class; 12162306a36Sopenharmony_ci 12262306a36Sopenharmony_ci switch (ref_type) { 12362306a36Sopenharmony_ci case ACPI_REFCLASS_LOCAL: 12462306a36Sopenharmony_ci case ACPI_REFCLASS_ARG: 12562306a36Sopenharmony_ci /* 12662306a36Sopenharmony_ci * Get the local from the method's state info 12762306a36Sopenharmony_ci * Note: this increments the local's object reference count 12862306a36Sopenharmony_ci */ 12962306a36Sopenharmony_ci status = acpi_ds_method_data_get_value(ref_type, 13062306a36Sopenharmony_ci stack_desc-> 13162306a36Sopenharmony_ci reference.value, 13262306a36Sopenharmony_ci walk_state, 13362306a36Sopenharmony_ci &obj_desc); 13462306a36Sopenharmony_ci if (ACPI_FAILURE(status)) { 13562306a36Sopenharmony_ci return_ACPI_STATUS(status); 13662306a36Sopenharmony_ci } 13762306a36Sopenharmony_ci 13862306a36Sopenharmony_ci ACPI_DEBUG_PRINT((ACPI_DB_EXEC, 13962306a36Sopenharmony_ci "[Arg/Local %X] ValueObj is %p\n", 14062306a36Sopenharmony_ci stack_desc->reference.value, 14162306a36Sopenharmony_ci obj_desc)); 14262306a36Sopenharmony_ci 14362306a36Sopenharmony_ci /* 14462306a36Sopenharmony_ci * Now we can delete the original Reference Object and 14562306a36Sopenharmony_ci * replace it with the resolved value 14662306a36Sopenharmony_ci */ 14762306a36Sopenharmony_ci acpi_ut_remove_reference(stack_desc); 14862306a36Sopenharmony_ci *stack_ptr = obj_desc; 14962306a36Sopenharmony_ci break; 15062306a36Sopenharmony_ci 15162306a36Sopenharmony_ci case ACPI_REFCLASS_INDEX: 15262306a36Sopenharmony_ci 15362306a36Sopenharmony_ci switch (stack_desc->reference.target_type) { 15462306a36Sopenharmony_ci case ACPI_TYPE_BUFFER_FIELD: 15562306a36Sopenharmony_ci 15662306a36Sopenharmony_ci /* Just return - do not dereference */ 15762306a36Sopenharmony_ci break; 15862306a36Sopenharmony_ci 15962306a36Sopenharmony_ci case ACPI_TYPE_PACKAGE: 16062306a36Sopenharmony_ci 16162306a36Sopenharmony_ci /* If method call or copy_object - do not dereference */ 16262306a36Sopenharmony_ci 16362306a36Sopenharmony_ci if ((walk_state->opcode == 16462306a36Sopenharmony_ci AML_INT_METHODCALL_OP) 16562306a36Sopenharmony_ci || (walk_state->opcode == 16662306a36Sopenharmony_ci AML_COPY_OBJECT_OP)) { 16762306a36Sopenharmony_ci break; 16862306a36Sopenharmony_ci } 16962306a36Sopenharmony_ci 17062306a36Sopenharmony_ci /* Otherwise, dereference the package_index to a package element */ 17162306a36Sopenharmony_ci 17262306a36Sopenharmony_ci obj_desc = *stack_desc->reference.where; 17362306a36Sopenharmony_ci if (obj_desc) { 17462306a36Sopenharmony_ci /* 17562306a36Sopenharmony_ci * Valid object descriptor, copy pointer to return value 17662306a36Sopenharmony_ci * (i.e., dereference the package index) 17762306a36Sopenharmony_ci * Delete the ref object, increment the returned object 17862306a36Sopenharmony_ci */ 17962306a36Sopenharmony_ci acpi_ut_add_reference(obj_desc); 18062306a36Sopenharmony_ci *stack_ptr = obj_desc; 18162306a36Sopenharmony_ci } else { 18262306a36Sopenharmony_ci /* 18362306a36Sopenharmony_ci * A NULL object descriptor means an uninitialized element of 18462306a36Sopenharmony_ci * the package, can't dereference it 18562306a36Sopenharmony_ci */ 18662306a36Sopenharmony_ci ACPI_ERROR((AE_INFO, 18762306a36Sopenharmony_ci "Attempt to dereference an Index to " 18862306a36Sopenharmony_ci "NULL package element Idx=%p", 18962306a36Sopenharmony_ci stack_desc)); 19062306a36Sopenharmony_ci status = AE_AML_UNINITIALIZED_ELEMENT; 19162306a36Sopenharmony_ci } 19262306a36Sopenharmony_ci break; 19362306a36Sopenharmony_ci 19462306a36Sopenharmony_ci default: 19562306a36Sopenharmony_ci 19662306a36Sopenharmony_ci /* Invalid reference object */ 19762306a36Sopenharmony_ci 19862306a36Sopenharmony_ci ACPI_ERROR((AE_INFO, 19962306a36Sopenharmony_ci "Unknown TargetType 0x%X in Index/Reference object %p", 20062306a36Sopenharmony_ci stack_desc->reference.target_type, 20162306a36Sopenharmony_ci stack_desc)); 20262306a36Sopenharmony_ci status = AE_AML_INTERNAL; 20362306a36Sopenharmony_ci break; 20462306a36Sopenharmony_ci } 20562306a36Sopenharmony_ci break; 20662306a36Sopenharmony_ci 20762306a36Sopenharmony_ci case ACPI_REFCLASS_REFOF: 20862306a36Sopenharmony_ci case ACPI_REFCLASS_DEBUG: 20962306a36Sopenharmony_ci case ACPI_REFCLASS_TABLE: 21062306a36Sopenharmony_ci 21162306a36Sopenharmony_ci /* Just leave the object as-is, do not dereference */ 21262306a36Sopenharmony_ci 21362306a36Sopenharmony_ci break; 21462306a36Sopenharmony_ci 21562306a36Sopenharmony_ci case ACPI_REFCLASS_NAME: /* Reference to a named object */ 21662306a36Sopenharmony_ci 21762306a36Sopenharmony_ci /* Dereference the name */ 21862306a36Sopenharmony_ci 21962306a36Sopenharmony_ci if ((stack_desc->reference.node->type == 22062306a36Sopenharmony_ci ACPI_TYPE_DEVICE) 22162306a36Sopenharmony_ci || (stack_desc->reference.node->type == 22262306a36Sopenharmony_ci ACPI_TYPE_THERMAL)) { 22362306a36Sopenharmony_ci 22462306a36Sopenharmony_ci /* These node types do not have 'real' subobjects */ 22562306a36Sopenharmony_ci 22662306a36Sopenharmony_ci *stack_ptr = (void *)stack_desc->reference.node; 22762306a36Sopenharmony_ci } else { 22862306a36Sopenharmony_ci /* Get the object pointed to by the namespace node */ 22962306a36Sopenharmony_ci 23062306a36Sopenharmony_ci *stack_ptr = 23162306a36Sopenharmony_ci (stack_desc->reference.node)->object; 23262306a36Sopenharmony_ci acpi_ut_add_reference(*stack_ptr); 23362306a36Sopenharmony_ci } 23462306a36Sopenharmony_ci 23562306a36Sopenharmony_ci acpi_ut_remove_reference(stack_desc); 23662306a36Sopenharmony_ci break; 23762306a36Sopenharmony_ci 23862306a36Sopenharmony_ci default: 23962306a36Sopenharmony_ci 24062306a36Sopenharmony_ci ACPI_ERROR((AE_INFO, 24162306a36Sopenharmony_ci "Unknown Reference type 0x%X in %p", 24262306a36Sopenharmony_ci ref_type, stack_desc)); 24362306a36Sopenharmony_ci status = AE_AML_INTERNAL; 24462306a36Sopenharmony_ci break; 24562306a36Sopenharmony_ci } 24662306a36Sopenharmony_ci break; 24762306a36Sopenharmony_ci 24862306a36Sopenharmony_ci case ACPI_TYPE_BUFFER: 24962306a36Sopenharmony_ci 25062306a36Sopenharmony_ci status = acpi_ds_get_buffer_arguments(stack_desc); 25162306a36Sopenharmony_ci break; 25262306a36Sopenharmony_ci 25362306a36Sopenharmony_ci case ACPI_TYPE_PACKAGE: 25462306a36Sopenharmony_ci 25562306a36Sopenharmony_ci status = acpi_ds_get_package_arguments(stack_desc); 25662306a36Sopenharmony_ci break; 25762306a36Sopenharmony_ci 25862306a36Sopenharmony_ci case ACPI_TYPE_BUFFER_FIELD: 25962306a36Sopenharmony_ci case ACPI_TYPE_LOCAL_REGION_FIELD: 26062306a36Sopenharmony_ci case ACPI_TYPE_LOCAL_BANK_FIELD: 26162306a36Sopenharmony_ci case ACPI_TYPE_LOCAL_INDEX_FIELD: 26262306a36Sopenharmony_ci 26362306a36Sopenharmony_ci ACPI_DEBUG_PRINT((ACPI_DB_EXEC, 26462306a36Sopenharmony_ci "FieldRead SourceDesc=%p Type=%X\n", 26562306a36Sopenharmony_ci stack_desc, stack_desc->common.type)); 26662306a36Sopenharmony_ci 26762306a36Sopenharmony_ci status = 26862306a36Sopenharmony_ci acpi_ex_read_data_from_field(walk_state, stack_desc, 26962306a36Sopenharmony_ci &obj_desc); 27062306a36Sopenharmony_ci 27162306a36Sopenharmony_ci /* Remove a reference to the original operand, then override */ 27262306a36Sopenharmony_ci 27362306a36Sopenharmony_ci acpi_ut_remove_reference(*stack_ptr); 27462306a36Sopenharmony_ci *stack_ptr = (void *)obj_desc; 27562306a36Sopenharmony_ci break; 27662306a36Sopenharmony_ci 27762306a36Sopenharmony_ci default: 27862306a36Sopenharmony_ci 27962306a36Sopenharmony_ci break; 28062306a36Sopenharmony_ci } 28162306a36Sopenharmony_ci 28262306a36Sopenharmony_ci return_ACPI_STATUS(status); 28362306a36Sopenharmony_ci} 28462306a36Sopenharmony_ci 28562306a36Sopenharmony_ci/******************************************************************************* 28662306a36Sopenharmony_ci * 28762306a36Sopenharmony_ci * FUNCTION: acpi_ex_resolve_multiple 28862306a36Sopenharmony_ci * 28962306a36Sopenharmony_ci * PARAMETERS: walk_state - Current state (contains AML opcode) 29062306a36Sopenharmony_ci * operand - Starting point for resolution 29162306a36Sopenharmony_ci * return_type - Where the object type is returned 29262306a36Sopenharmony_ci * return_desc - Where the resolved object is returned 29362306a36Sopenharmony_ci * 29462306a36Sopenharmony_ci * RETURN: Status 29562306a36Sopenharmony_ci * 29662306a36Sopenharmony_ci * DESCRIPTION: Return the base object and type. Traverse a reference list if 29762306a36Sopenharmony_ci * necessary to get to the base object. 29862306a36Sopenharmony_ci * 29962306a36Sopenharmony_ci ******************************************************************************/ 30062306a36Sopenharmony_ci 30162306a36Sopenharmony_ciacpi_status 30262306a36Sopenharmony_ciacpi_ex_resolve_multiple(struct acpi_walk_state *walk_state, 30362306a36Sopenharmony_ci union acpi_operand_object *operand, 30462306a36Sopenharmony_ci acpi_object_type *return_type, 30562306a36Sopenharmony_ci union acpi_operand_object **return_desc) 30662306a36Sopenharmony_ci{ 30762306a36Sopenharmony_ci union acpi_operand_object *obj_desc = ACPI_CAST_PTR(void, operand); 30862306a36Sopenharmony_ci struct acpi_namespace_node *node = 30962306a36Sopenharmony_ci ACPI_CAST_PTR(struct acpi_namespace_node, operand); 31062306a36Sopenharmony_ci acpi_object_type type; 31162306a36Sopenharmony_ci acpi_status status; 31262306a36Sopenharmony_ci 31362306a36Sopenharmony_ci ACPI_FUNCTION_TRACE(acpi_ex_resolve_multiple); 31462306a36Sopenharmony_ci 31562306a36Sopenharmony_ci /* Operand can be either a namespace node or an operand descriptor */ 31662306a36Sopenharmony_ci 31762306a36Sopenharmony_ci switch (ACPI_GET_DESCRIPTOR_TYPE(obj_desc)) { 31862306a36Sopenharmony_ci case ACPI_DESC_TYPE_OPERAND: 31962306a36Sopenharmony_ci 32062306a36Sopenharmony_ci type = obj_desc->common.type; 32162306a36Sopenharmony_ci break; 32262306a36Sopenharmony_ci 32362306a36Sopenharmony_ci case ACPI_DESC_TYPE_NAMED: 32462306a36Sopenharmony_ci 32562306a36Sopenharmony_ci type = ((struct acpi_namespace_node *)obj_desc)->type; 32662306a36Sopenharmony_ci obj_desc = acpi_ns_get_attached_object(node); 32762306a36Sopenharmony_ci 32862306a36Sopenharmony_ci /* If we had an Alias node, use the attached object for type info */ 32962306a36Sopenharmony_ci 33062306a36Sopenharmony_ci if (type == ACPI_TYPE_LOCAL_ALIAS) { 33162306a36Sopenharmony_ci type = ((struct acpi_namespace_node *)obj_desc)->type; 33262306a36Sopenharmony_ci obj_desc = acpi_ns_get_attached_object((struct 33362306a36Sopenharmony_ci acpi_namespace_node 33462306a36Sopenharmony_ci *)obj_desc); 33562306a36Sopenharmony_ci } 33662306a36Sopenharmony_ci 33762306a36Sopenharmony_ci switch (type) { 33862306a36Sopenharmony_ci case ACPI_TYPE_DEVICE: 33962306a36Sopenharmony_ci case ACPI_TYPE_THERMAL: 34062306a36Sopenharmony_ci 34162306a36Sopenharmony_ci /* These types have no attached subobject */ 34262306a36Sopenharmony_ci break; 34362306a36Sopenharmony_ci 34462306a36Sopenharmony_ci default: 34562306a36Sopenharmony_ci 34662306a36Sopenharmony_ci /* All other types require a subobject */ 34762306a36Sopenharmony_ci 34862306a36Sopenharmony_ci if (!obj_desc) { 34962306a36Sopenharmony_ci ACPI_ERROR((AE_INFO, 35062306a36Sopenharmony_ci "[%4.4s] Node is unresolved or uninitialized", 35162306a36Sopenharmony_ci acpi_ut_get_node_name(node))); 35262306a36Sopenharmony_ci return_ACPI_STATUS(AE_AML_UNINITIALIZED_NODE); 35362306a36Sopenharmony_ci } 35462306a36Sopenharmony_ci break; 35562306a36Sopenharmony_ci } 35662306a36Sopenharmony_ci break; 35762306a36Sopenharmony_ci 35862306a36Sopenharmony_ci default: 35962306a36Sopenharmony_ci return_ACPI_STATUS(AE_AML_OPERAND_TYPE); 36062306a36Sopenharmony_ci } 36162306a36Sopenharmony_ci 36262306a36Sopenharmony_ci /* If type is anything other than a reference, we are done */ 36362306a36Sopenharmony_ci 36462306a36Sopenharmony_ci if (type != ACPI_TYPE_LOCAL_REFERENCE) { 36562306a36Sopenharmony_ci goto exit; 36662306a36Sopenharmony_ci } 36762306a36Sopenharmony_ci 36862306a36Sopenharmony_ci /* 36962306a36Sopenharmony_ci * For reference objects created via the ref_of, Index, or Load/load_table 37062306a36Sopenharmony_ci * operators, we need to get to the base object (as per the ACPI 37162306a36Sopenharmony_ci * specification of the object_type and size_of operators). This means 37262306a36Sopenharmony_ci * traversing the list of possibly many nested references. 37362306a36Sopenharmony_ci */ 37462306a36Sopenharmony_ci while (obj_desc->common.type == ACPI_TYPE_LOCAL_REFERENCE) { 37562306a36Sopenharmony_ci switch (obj_desc->reference.class) { 37662306a36Sopenharmony_ci case ACPI_REFCLASS_REFOF: 37762306a36Sopenharmony_ci case ACPI_REFCLASS_NAME: 37862306a36Sopenharmony_ci 37962306a36Sopenharmony_ci /* Dereference the reference pointer */ 38062306a36Sopenharmony_ci 38162306a36Sopenharmony_ci if (obj_desc->reference.class == ACPI_REFCLASS_REFOF) { 38262306a36Sopenharmony_ci node = obj_desc->reference.object; 38362306a36Sopenharmony_ci } else { /* AML_INT_NAMEPATH_OP */ 38462306a36Sopenharmony_ci 38562306a36Sopenharmony_ci node = obj_desc->reference.node; 38662306a36Sopenharmony_ci } 38762306a36Sopenharmony_ci 38862306a36Sopenharmony_ci /* All "References" point to a NS node */ 38962306a36Sopenharmony_ci 39062306a36Sopenharmony_ci if (ACPI_GET_DESCRIPTOR_TYPE(node) != 39162306a36Sopenharmony_ci ACPI_DESC_TYPE_NAMED) { 39262306a36Sopenharmony_ci ACPI_ERROR((AE_INFO, 39362306a36Sopenharmony_ci "Not a namespace node %p [%s]", 39462306a36Sopenharmony_ci node, 39562306a36Sopenharmony_ci acpi_ut_get_descriptor_name(node))); 39662306a36Sopenharmony_ci return_ACPI_STATUS(AE_AML_INTERNAL); 39762306a36Sopenharmony_ci } 39862306a36Sopenharmony_ci 39962306a36Sopenharmony_ci /* Get the attached object */ 40062306a36Sopenharmony_ci 40162306a36Sopenharmony_ci obj_desc = acpi_ns_get_attached_object(node); 40262306a36Sopenharmony_ci if (!obj_desc) { 40362306a36Sopenharmony_ci 40462306a36Sopenharmony_ci /* No object, use the NS node type */ 40562306a36Sopenharmony_ci 40662306a36Sopenharmony_ci type = acpi_ns_get_type(node); 40762306a36Sopenharmony_ci goto exit; 40862306a36Sopenharmony_ci } 40962306a36Sopenharmony_ci 41062306a36Sopenharmony_ci /* Check for circular references */ 41162306a36Sopenharmony_ci 41262306a36Sopenharmony_ci if (obj_desc == operand) { 41362306a36Sopenharmony_ci return_ACPI_STATUS(AE_AML_CIRCULAR_REFERENCE); 41462306a36Sopenharmony_ci } 41562306a36Sopenharmony_ci break; 41662306a36Sopenharmony_ci 41762306a36Sopenharmony_ci case ACPI_REFCLASS_INDEX: 41862306a36Sopenharmony_ci 41962306a36Sopenharmony_ci /* Get the type of this reference (index into another object) */ 42062306a36Sopenharmony_ci 42162306a36Sopenharmony_ci type = obj_desc->reference.target_type; 42262306a36Sopenharmony_ci if (type != ACPI_TYPE_PACKAGE) { 42362306a36Sopenharmony_ci goto exit; 42462306a36Sopenharmony_ci } 42562306a36Sopenharmony_ci 42662306a36Sopenharmony_ci /* 42762306a36Sopenharmony_ci * The main object is a package, we want to get the type 42862306a36Sopenharmony_ci * of the individual package element that is referenced by 42962306a36Sopenharmony_ci * the index. 43062306a36Sopenharmony_ci * 43162306a36Sopenharmony_ci * This could of course in turn be another reference object. 43262306a36Sopenharmony_ci */ 43362306a36Sopenharmony_ci obj_desc = *(obj_desc->reference.where); 43462306a36Sopenharmony_ci if (!obj_desc) { 43562306a36Sopenharmony_ci 43662306a36Sopenharmony_ci /* NULL package elements are allowed */ 43762306a36Sopenharmony_ci 43862306a36Sopenharmony_ci type = 0; /* Uninitialized */ 43962306a36Sopenharmony_ci goto exit; 44062306a36Sopenharmony_ci } 44162306a36Sopenharmony_ci break; 44262306a36Sopenharmony_ci 44362306a36Sopenharmony_ci case ACPI_REFCLASS_TABLE: 44462306a36Sopenharmony_ci 44562306a36Sopenharmony_ci type = ACPI_TYPE_DDB_HANDLE; 44662306a36Sopenharmony_ci goto exit; 44762306a36Sopenharmony_ci 44862306a36Sopenharmony_ci case ACPI_REFCLASS_LOCAL: 44962306a36Sopenharmony_ci case ACPI_REFCLASS_ARG: 45062306a36Sopenharmony_ci 45162306a36Sopenharmony_ci if (return_desc) { 45262306a36Sopenharmony_ci status = 45362306a36Sopenharmony_ci acpi_ds_method_data_get_value(obj_desc-> 45462306a36Sopenharmony_ci reference. 45562306a36Sopenharmony_ci class, 45662306a36Sopenharmony_ci obj_desc-> 45762306a36Sopenharmony_ci reference. 45862306a36Sopenharmony_ci value, 45962306a36Sopenharmony_ci walk_state, 46062306a36Sopenharmony_ci &obj_desc); 46162306a36Sopenharmony_ci if (ACPI_FAILURE(status)) { 46262306a36Sopenharmony_ci return_ACPI_STATUS(status); 46362306a36Sopenharmony_ci } 46462306a36Sopenharmony_ci acpi_ut_remove_reference(obj_desc); 46562306a36Sopenharmony_ci } else { 46662306a36Sopenharmony_ci status = 46762306a36Sopenharmony_ci acpi_ds_method_data_get_node(obj_desc-> 46862306a36Sopenharmony_ci reference. 46962306a36Sopenharmony_ci class, 47062306a36Sopenharmony_ci obj_desc-> 47162306a36Sopenharmony_ci reference. 47262306a36Sopenharmony_ci value, 47362306a36Sopenharmony_ci walk_state, 47462306a36Sopenharmony_ci &node); 47562306a36Sopenharmony_ci if (ACPI_FAILURE(status)) { 47662306a36Sopenharmony_ci return_ACPI_STATUS(status); 47762306a36Sopenharmony_ci } 47862306a36Sopenharmony_ci 47962306a36Sopenharmony_ci obj_desc = acpi_ns_get_attached_object(node); 48062306a36Sopenharmony_ci if (!obj_desc) { 48162306a36Sopenharmony_ci type = ACPI_TYPE_ANY; 48262306a36Sopenharmony_ci goto exit; 48362306a36Sopenharmony_ci } 48462306a36Sopenharmony_ci } 48562306a36Sopenharmony_ci break; 48662306a36Sopenharmony_ci 48762306a36Sopenharmony_ci case ACPI_REFCLASS_DEBUG: 48862306a36Sopenharmony_ci 48962306a36Sopenharmony_ci /* The Debug Object is of type "DebugObject" */ 49062306a36Sopenharmony_ci 49162306a36Sopenharmony_ci type = ACPI_TYPE_DEBUG_OBJECT; 49262306a36Sopenharmony_ci goto exit; 49362306a36Sopenharmony_ci 49462306a36Sopenharmony_ci default: 49562306a36Sopenharmony_ci 49662306a36Sopenharmony_ci ACPI_ERROR((AE_INFO, 49762306a36Sopenharmony_ci "Unknown Reference Class 0x%2.2X", 49862306a36Sopenharmony_ci obj_desc->reference.class)); 49962306a36Sopenharmony_ci return_ACPI_STATUS(AE_AML_INTERNAL); 50062306a36Sopenharmony_ci } 50162306a36Sopenharmony_ci } 50262306a36Sopenharmony_ci 50362306a36Sopenharmony_ci /* 50462306a36Sopenharmony_ci * Now we are guaranteed to have an object that has not been created 50562306a36Sopenharmony_ci * via the ref_of or Index operators. 50662306a36Sopenharmony_ci */ 50762306a36Sopenharmony_ci type = obj_desc->common.type; 50862306a36Sopenharmony_ci 50962306a36Sopenharmony_ciexit: 51062306a36Sopenharmony_ci /* Convert internal types to external types */ 51162306a36Sopenharmony_ci 51262306a36Sopenharmony_ci switch (type) { 51362306a36Sopenharmony_ci case ACPI_TYPE_LOCAL_REGION_FIELD: 51462306a36Sopenharmony_ci case ACPI_TYPE_LOCAL_BANK_FIELD: 51562306a36Sopenharmony_ci case ACPI_TYPE_LOCAL_INDEX_FIELD: 51662306a36Sopenharmony_ci 51762306a36Sopenharmony_ci type = ACPI_TYPE_FIELD_UNIT; 51862306a36Sopenharmony_ci break; 51962306a36Sopenharmony_ci 52062306a36Sopenharmony_ci case ACPI_TYPE_LOCAL_SCOPE: 52162306a36Sopenharmony_ci 52262306a36Sopenharmony_ci /* Per ACPI Specification, Scope is untyped */ 52362306a36Sopenharmony_ci 52462306a36Sopenharmony_ci type = ACPI_TYPE_ANY; 52562306a36Sopenharmony_ci break; 52662306a36Sopenharmony_ci 52762306a36Sopenharmony_ci default: 52862306a36Sopenharmony_ci 52962306a36Sopenharmony_ci /* No change to Type required */ 53062306a36Sopenharmony_ci 53162306a36Sopenharmony_ci break; 53262306a36Sopenharmony_ci } 53362306a36Sopenharmony_ci 53462306a36Sopenharmony_ci *return_type = type; 53562306a36Sopenharmony_ci if (return_desc) { 53662306a36Sopenharmony_ci *return_desc = obj_desc; 53762306a36Sopenharmony_ci } 53862306a36Sopenharmony_ci return_ACPI_STATUS(AE_OK); 53962306a36Sopenharmony_ci} 540