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 - 2023, 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
acpi_ex_resolve_node_to_value(struct acpi_namespace_node ** object_ptr,struct acpi_walk_state * walk_state)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