1 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 2 /****************************************************************************** 3 * 4 * Module Name: exresnte - AML Interpreter object resolution 5 * 6 * Copyright (C) 2000 - 2020, Intel Corp. 7 * 8 *****************************************************************************/ 9 10 #include <acpi/acpi.h> 11 #include "accommon.h" 12 #include "acdispat.h" 13 #include "acinterp.h" 14 #include "acnamesp.h" 15 16 #define _COMPONENT ACPI_EXECUTER 17 ACPI_MODULE_NAME("exresnte") 18 19 /******************************************************************************* 20 * 21 * FUNCTION: acpi_ex_resolve_node_to_value 22 * 23 * PARAMETERS: object_ptr - Pointer to a location that contains 24 * a pointer to a NS node, and will receive a 25 * pointer to the resolved object. 26 * walk_state - Current state. Valid only if executing AML 27 * code. NULL if simply resolving an object 28 * 29 * RETURN: Status 30 * 31 * DESCRIPTION: Resolve a Namespace node to a valued object 32 * 33 * Note: for some of the data types, the pointer attached to the Node 34 * can be either a pointer to an actual internal object or a pointer into the 35 * AML stream itself. These types are currently: 36 * 37 * ACPI_TYPE_INTEGER 38 * ACPI_TYPE_STRING 39 * ACPI_TYPE_BUFFER 40 * ACPI_TYPE_MUTEX 41 * ACPI_TYPE_PACKAGE 42 * 43 ******************************************************************************/ 44 acpi_status 45 acpi_ex_resolve_node_to_value(struct acpi_namespace_node **object_ptr, 46 struct acpi_walk_state *walk_state) 47 { 48 acpi_status status = AE_OK; 49 union acpi_operand_object *source_desc; 50 union acpi_operand_object *obj_desc = NULL; 51 struct acpi_namespace_node *node; 52 acpi_object_type entry_type; 53 54 ACPI_FUNCTION_TRACE(ex_resolve_node_to_value); 55 56 /* 57 * The stack pointer points to a struct acpi_namespace_node (Node). Get the 58 * object that is attached to the Node. 59 */ 60 node = *object_ptr; 61 source_desc = acpi_ns_get_attached_object(node); 62 entry_type = acpi_ns_get_type((acpi_handle)node); 63 64 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Entry=%p SourceDesc=%p [%s]\n", 65 node, source_desc, 66 acpi_ut_get_type_name(entry_type))); 67 68 if ((entry_type == ACPI_TYPE_LOCAL_ALIAS) || 69 (entry_type == ACPI_TYPE_LOCAL_METHOD_ALIAS)) { 70 71 /* There is always exactly one level of indirection */ 72 73 node = ACPI_CAST_PTR(struct acpi_namespace_node, node->object); 74 source_desc = acpi_ns_get_attached_object(node); 75 entry_type = acpi_ns_get_type((acpi_handle)node); 76 *object_ptr = node; 77 } 78 79 /* 80 * Several object types require no further processing: 81 * 1) Device/Thermal objects don't have a "real" subobject, return Node 82 * 2) Method locals and arguments have a pseudo-Node 83 * 3) 10/2007: Added method type to assist with Package construction. 84 */ 85 if ((entry_type == ACPI_TYPE_DEVICE) || 86 (entry_type == ACPI_TYPE_THERMAL) || 87 (entry_type == ACPI_TYPE_METHOD) || 88 (node->flags & (ANOBJ_METHOD_ARG | ANOBJ_METHOD_LOCAL))) { 89 return_ACPI_STATUS(AE_OK); 90 } 91 92 if (!source_desc) { 93 ACPI_ERROR((AE_INFO, "No object attached to node [%4.4s] %p", 94 node->name.ascii, node)); 95 return_ACPI_STATUS(AE_AML_UNINITIALIZED_NODE); 96 } 97 98 /* 99 * Action is based on the type of the Node, which indicates the type 100 * of the attached object or pointer 101 */ 102 switch (entry_type) { 103 case ACPI_TYPE_PACKAGE: 104 105 if (source_desc->common.type != ACPI_TYPE_PACKAGE) { 106 ACPI_ERROR((AE_INFO, "Object not a Package, type %s", 107 acpi_ut_get_object_type_name(source_desc))); 108 return_ACPI_STATUS(AE_AML_OPERAND_TYPE); 109 } 110 111 status = acpi_ds_get_package_arguments(source_desc); 112 if (ACPI_SUCCESS(status)) { 113 114 /* Return an additional reference to the object */ 115 116 obj_desc = source_desc; 117 acpi_ut_add_reference(obj_desc); 118 } 119 break; 120 121 case ACPI_TYPE_BUFFER: 122 123 if (source_desc->common.type != ACPI_TYPE_BUFFER) { 124 ACPI_ERROR((AE_INFO, "Object not a Buffer, type %s", 125 acpi_ut_get_object_type_name(source_desc))); 126 return_ACPI_STATUS(AE_AML_OPERAND_TYPE); 127 } 128 129 status = acpi_ds_get_buffer_arguments(source_desc); 130 if (ACPI_SUCCESS(status)) { 131 132 /* Return an additional reference to the object */ 133 134 obj_desc = source_desc; 135 acpi_ut_add_reference(obj_desc); 136 } 137 break; 138 139 case ACPI_TYPE_STRING: 140 141 if (source_desc->common.type != ACPI_TYPE_STRING) { 142 ACPI_ERROR((AE_INFO, "Object not a String, type %s", 143 acpi_ut_get_object_type_name(source_desc))); 144 return_ACPI_STATUS(AE_AML_OPERAND_TYPE); 145 } 146 147 /* Return an additional reference to the object */ 148 149 obj_desc = source_desc; 150 acpi_ut_add_reference(obj_desc); 151 break; 152 153 case ACPI_TYPE_INTEGER: 154 155 if (source_desc->common.type != ACPI_TYPE_INTEGER) { 156 ACPI_ERROR((AE_INFO, "Object not a Integer, type %s", 157 acpi_ut_get_object_type_name(source_desc))); 158 return_ACPI_STATUS(AE_AML_OPERAND_TYPE); 159 } 160 161 /* Return an additional reference to the object */ 162 163 obj_desc = source_desc; 164 acpi_ut_add_reference(obj_desc); 165 break; 166 167 case ACPI_TYPE_BUFFER_FIELD: 168 case ACPI_TYPE_LOCAL_REGION_FIELD: 169 case ACPI_TYPE_LOCAL_BANK_FIELD: 170 case ACPI_TYPE_LOCAL_INDEX_FIELD: 171 172 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, 173 "FieldRead Node=%p SourceDesc=%p Type=%X\n", 174 node, source_desc, entry_type)); 175 176 status = 177 acpi_ex_read_data_from_field(walk_state, source_desc, 178 &obj_desc); 179 break; 180 181 /* For these objects, just return the object attached to the Node */ 182 183 case ACPI_TYPE_MUTEX: 184 case ACPI_TYPE_POWER: 185 case ACPI_TYPE_PROCESSOR: 186 case ACPI_TYPE_EVENT: 187 case ACPI_TYPE_REGION: 188 189 /* Return an additional reference to the object */ 190 191 obj_desc = source_desc; 192 acpi_ut_add_reference(obj_desc); 193 break; 194 195 /* TYPE_ANY is untyped, and thus there is no object associated with it */ 196 197 case ACPI_TYPE_ANY: 198 199 ACPI_ERROR((AE_INFO, 200 "Untyped entry %p, no attached object!", node)); 201 202 return_ACPI_STATUS(AE_AML_OPERAND_TYPE); /* Cannot be AE_TYPE */ 203 204 case ACPI_TYPE_LOCAL_REFERENCE: 205 206 switch (source_desc->reference.class) { 207 case ACPI_REFCLASS_TABLE: /* This is a ddb_handle */ 208 case ACPI_REFCLASS_REFOF: 209 case ACPI_REFCLASS_INDEX: 210 211 /* Return an additional reference to the object */ 212 213 obj_desc = source_desc; 214 acpi_ut_add_reference(obj_desc); 215 break; 216 217 default: 218 219 /* No named references are allowed here */ 220 221 ACPI_ERROR((AE_INFO, 222 "Unsupported Reference type 0x%X", 223 source_desc->reference.class)); 224 225 return_ACPI_STATUS(AE_AML_OPERAND_TYPE); 226 } 227 break; 228 229 default: 230 231 /* Default case is for unknown types */ 232 233 ACPI_ERROR((AE_INFO, 234 "Node %p - Unknown object type 0x%X", 235 node, entry_type)); 236 237 return_ACPI_STATUS(AE_AML_OPERAND_TYPE); 238 239 } /* switch (entry_type) */ 240 241 /* Return the object descriptor */ 242 243 *object_ptr = (void *)obj_desc; 244 return_ACPI_STATUS(status); 245 } 246