1 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
2 /******************************************************************************
3  *
4  * Module Name: exstore - AML Interpreter object store support
5  *
6  * Copyright (C) 2000 - 2022, Intel Corp.
7  *
8  *****************************************************************************/
9 
10 #include <acpi/acpi.h>
11 #include "accommon.h"
12 #include "acdispat.h"
13 #include "acinterp.h"
14 #include "amlcode.h"
15 #include "acnamesp.h"
16 
17 #define _COMPONENT          ACPI_EXECUTER
18 ACPI_MODULE_NAME("exstore")
19 
20 /* Local prototypes */
21 static acpi_status
22 acpi_ex_store_object_to_index(union acpi_operand_object *val_desc,
23 			      union acpi_operand_object *dest_desc,
24 			      struct acpi_walk_state *walk_state);
25 
26 static acpi_status
27 acpi_ex_store_direct_to_node(union acpi_operand_object *source_desc,
28 			     struct acpi_namespace_node *node,
29 			     struct acpi_walk_state *walk_state);
30 
31 /*******************************************************************************
32  *
33  * FUNCTION:    acpi_ex_store
34  *
35  * PARAMETERS:  *source_desc        - Value to be stored
36  *              *dest_desc          - Where to store it. Must be an NS node
37  *                                    or union acpi_operand_object of type
38  *                                    Reference;
39  *              walk_state          - Current walk state
40  *
41  * RETURN:      Status
42  *
43  * DESCRIPTION: Store the value described by source_desc into the location
44  *              described by dest_desc. Called by various interpreter
45  *              functions to store the result of an operation into
46  *              the destination operand -- not just simply the actual "Store"
47  *              ASL operator.
48  *
49  ******************************************************************************/
50 
51 acpi_status
acpi_ex_store(union acpi_operand_object * source_desc,union acpi_operand_object * dest_desc,struct acpi_walk_state * walk_state)52 acpi_ex_store(union acpi_operand_object *source_desc,
53 	      union acpi_operand_object *dest_desc,
54 	      struct acpi_walk_state *walk_state)
55 {
56 	acpi_status status = AE_OK;
57 	union acpi_operand_object *ref_desc = dest_desc;
58 
59 	ACPI_FUNCTION_TRACE_PTR(ex_store, dest_desc);
60 
61 	/* Validate parameters */
62 
63 	if (!source_desc || !dest_desc) {
64 		ACPI_ERROR((AE_INFO, "Null parameter"));
65 		return_ACPI_STATUS(AE_AML_NO_OPERAND);
66 	}
67 
68 	/* dest_desc can be either a namespace node or an ACPI object */
69 
70 	if (ACPI_GET_DESCRIPTOR_TYPE(dest_desc) == ACPI_DESC_TYPE_NAMED) {
71 		/*
72 		 * Dest is a namespace node,
73 		 * Storing an object into a Named node.
74 		 */
75 		status = acpi_ex_store_object_to_node(source_desc,
76 						      (struct
77 						       acpi_namespace_node *)
78 						      dest_desc, walk_state,
79 						      ACPI_IMPLICIT_CONVERSION);
80 
81 		return_ACPI_STATUS(status);
82 	}
83 
84 	/* Destination object must be a Reference or a Constant object */
85 
86 	switch (dest_desc->common.type) {
87 	case ACPI_TYPE_LOCAL_REFERENCE:
88 
89 		break;
90 
91 	case ACPI_TYPE_INTEGER:
92 
93 		/* Allow stores to Constants -- a Noop as per ACPI spec */
94 
95 		if (dest_desc->common.flags & AOPOBJ_AML_CONSTANT) {
96 			return_ACPI_STATUS(AE_OK);
97 		}
98 
99 		ACPI_FALLTHROUGH;
100 
101 	default:
102 
103 		/* Destination is not a Reference object */
104 
105 		ACPI_ERROR((AE_INFO,
106 			    "Target is not a Reference or Constant object - [%s] %p",
107 			    acpi_ut_get_object_type_name(dest_desc),
108 			    dest_desc));
109 
110 		return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
111 	}
112 
113 	/*
114 	 * Examine the Reference class. These cases are handled:
115 	 *
116 	 * 1) Store to Name (Change the object associated with a name)
117 	 * 2) Store to an indexed area of a Buffer or Package
118 	 * 3) Store to a Method Local or Arg
119 	 * 4) Store to the debug object
120 	 */
121 	switch (ref_desc->reference.class) {
122 	case ACPI_REFCLASS_REFOF:
123 
124 		/* Storing an object into a Name "container" */
125 
126 		status = acpi_ex_store_object_to_node(source_desc,
127 						      ref_desc->reference.
128 						      object, walk_state,
129 						      ACPI_IMPLICIT_CONVERSION);
130 		break;
131 
132 	case ACPI_REFCLASS_INDEX:
133 
134 		/* Storing to an Index (pointer into a packager or buffer) */
135 
136 		status =
137 		    acpi_ex_store_object_to_index(source_desc, ref_desc,
138 						  walk_state);
139 		break;
140 
141 	case ACPI_REFCLASS_LOCAL:
142 	case ACPI_REFCLASS_ARG:
143 
144 		/* Store to a method local/arg  */
145 
146 		status =
147 		    acpi_ds_store_object_to_local(ref_desc->reference.class,
148 						  ref_desc->reference.value,
149 						  source_desc, walk_state);
150 		break;
151 
152 	case ACPI_REFCLASS_DEBUG:
153 		/*
154 		 * Storing to the Debug object causes the value stored to be
155 		 * displayed and otherwise has no effect -- see ACPI Specification
156 		 */
157 		ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
158 				  "**** Write to Debug Object: Object %p [%s] ****:\n\n",
159 				  source_desc,
160 				  acpi_ut_get_object_type_name(source_desc)));
161 
162 		ACPI_DEBUG_OBJECT(source_desc, 0, 0);
163 		break;
164 
165 	default:
166 
167 		ACPI_ERROR((AE_INFO, "Unknown Reference Class 0x%2.2X",
168 			    ref_desc->reference.class));
169 		ACPI_DUMP_ENTRY(ref_desc, ACPI_LV_INFO);
170 
171 		status = AE_AML_INTERNAL;
172 		break;
173 	}
174 
175 	return_ACPI_STATUS(status);
176 }
177 
178 /*******************************************************************************
179  *
180  * FUNCTION:    acpi_ex_store_object_to_index
181  *
182  * PARAMETERS:  *source_desc            - Value to be stored
183  *              *dest_desc              - Named object to receive the value
184  *              walk_state              - Current walk state
185  *
186  * RETURN:      Status
187  *
188  * DESCRIPTION: Store the object to indexed Buffer or Package element
189  *
190  ******************************************************************************/
191 
192 static acpi_status
acpi_ex_store_object_to_index(union acpi_operand_object * source_desc,union acpi_operand_object * index_desc,struct acpi_walk_state * walk_state)193 acpi_ex_store_object_to_index(union acpi_operand_object *source_desc,
194 			      union acpi_operand_object *index_desc,
195 			      struct acpi_walk_state *walk_state)
196 {
197 	acpi_status status = AE_OK;
198 	union acpi_operand_object *obj_desc;
199 	union acpi_operand_object *new_desc;
200 	u8 value = 0;
201 	u32 i;
202 
203 	ACPI_FUNCTION_TRACE(ex_store_object_to_index);
204 
205 	/*
206 	 * Destination must be a reference pointer, and
207 	 * must point to either a buffer or a package
208 	 */
209 	switch (index_desc->reference.target_type) {
210 	case ACPI_TYPE_PACKAGE:
211 		/*
212 		 * Storing to a package element. Copy the object and replace
213 		 * any existing object with the new object. No implicit
214 		 * conversion is performed.
215 		 *
216 		 * The object at *(index_desc->Reference.Where) is the
217 		 * element within the package that is to be modified.
218 		 * The parent package object is at index_desc->Reference.Object
219 		 */
220 		obj_desc = *(index_desc->reference.where);
221 
222 		if (source_desc->common.type == ACPI_TYPE_LOCAL_REFERENCE &&
223 		    source_desc->reference.class == ACPI_REFCLASS_TABLE) {
224 
225 			/* This is a DDBHandle, just add a reference to it */
226 
227 			acpi_ut_add_reference(source_desc);
228 			new_desc = source_desc;
229 		} else {
230 			/* Normal object, copy it */
231 
232 			status =
233 			    acpi_ut_copy_iobject_to_iobject(source_desc,
234 							    &new_desc,
235 							    walk_state);
236 			if (ACPI_FAILURE(status)) {
237 				return_ACPI_STATUS(status);
238 			}
239 		}
240 
241 		if (obj_desc) {
242 
243 			/* Decrement reference count by the ref count of the parent package */
244 
245 			for (i = 0; i < ((union acpi_operand_object *)
246 					 index_desc->reference.object)->common.
247 			     reference_count; i++) {
248 				acpi_ut_remove_reference(obj_desc);
249 			}
250 		}
251 
252 		*(index_desc->reference.where) = new_desc;
253 
254 		/* Increment ref count by the ref count of the parent package-1 */
255 
256 		for (i = 1; i < ((union acpi_operand_object *)
257 				 index_desc->reference.object)->common.
258 		     reference_count; i++) {
259 			acpi_ut_add_reference(new_desc);
260 		}
261 
262 		break;
263 
264 	case ACPI_TYPE_BUFFER_FIELD:
265 		/*
266 		 * Store into a Buffer or String (not actually a real buffer_field)
267 		 * at a location defined by an Index.
268 		 *
269 		 * The first 8-bit element of the source object is written to the
270 		 * 8-bit Buffer location defined by the Index destination object,
271 		 * according to the ACPI 2.0 specification.
272 		 */
273 
274 		/*
275 		 * Make sure the target is a Buffer or String. An error should
276 		 * not happen here, since the reference_object was constructed
277 		 * by the INDEX_OP code.
278 		 */
279 		obj_desc = index_desc->reference.object;
280 		if ((obj_desc->common.type != ACPI_TYPE_BUFFER) &&
281 		    (obj_desc->common.type != ACPI_TYPE_STRING)) {
282 			return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
283 		}
284 
285 		/*
286 		 * The assignment of the individual elements will be slightly
287 		 * different for each source type.
288 		 */
289 		switch (source_desc->common.type) {
290 		case ACPI_TYPE_INTEGER:
291 
292 			/* Use the least-significant byte of the integer */
293 
294 			value = (u8) (source_desc->integer.value);
295 			break;
296 
297 		case ACPI_TYPE_BUFFER:
298 		case ACPI_TYPE_STRING:
299 
300 			/* Note: Takes advantage of common string/buffer fields */
301 
302 			value = source_desc->buffer.pointer[0];
303 			break;
304 
305 		default:
306 
307 			/* All other types are invalid */
308 
309 			ACPI_ERROR((AE_INFO,
310 				    "Source must be type [Integer/Buffer/String], found [%s]",
311 				    acpi_ut_get_object_type_name(source_desc)));
312 			return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
313 		}
314 
315 		/* Store the source value into the target buffer byte */
316 
317 		obj_desc->buffer.pointer[index_desc->reference.value] = value;
318 		break;
319 
320 	default:
321 		ACPI_ERROR((AE_INFO,
322 			    "Target is not of type [Package/BufferField]"));
323 		status = AE_AML_TARGET_TYPE;
324 		break;
325 	}
326 
327 	return_ACPI_STATUS(status);
328 }
329 
330 /*******************************************************************************
331  *
332  * FUNCTION:    acpi_ex_store_object_to_node
333  *
334  * PARAMETERS:  source_desc             - Value to be stored
335  *              node                    - Named object to receive the value
336  *              walk_state              - Current walk state
337  *              implicit_conversion     - Perform implicit conversion (yes/no)
338  *
339  * RETURN:      Status
340  *
341  * DESCRIPTION: Store the object to the named object.
342  *
343  * The assignment of an object to a named object is handled here.
344  * The value passed in will replace the current value (if any)
345  * with the input value.
346  *
347  * When storing into an object the data is converted to the
348  * target object type then stored in the object. This means
349  * that the target object type (for an initialized target) will
350  * not be changed by a store operation. A copy_object can change
351  * the target type, however.
352  *
353  * The implicit_conversion flag is set to NO/FALSE only when
354  * storing to an arg_x -- as per the rules of the ACPI spec.
355  *
356  * Assumes parameters are already validated.
357  *
358  ******************************************************************************/
359 
360 acpi_status
acpi_ex_store_object_to_node(union acpi_operand_object * source_desc,struct acpi_namespace_node * node,struct acpi_walk_state * walk_state,u8 implicit_conversion)361 acpi_ex_store_object_to_node(union acpi_operand_object *source_desc,
362 			     struct acpi_namespace_node *node,
363 			     struct acpi_walk_state *walk_state,
364 			     u8 implicit_conversion)
365 {
366 	acpi_status status = AE_OK;
367 	union acpi_operand_object *target_desc;
368 	union acpi_operand_object *new_desc;
369 	acpi_object_type target_type;
370 
371 	ACPI_FUNCTION_TRACE_PTR(ex_store_object_to_node, source_desc);
372 
373 	/* Get current type of the node, and object attached to Node */
374 
375 	target_type = acpi_ns_get_type(node);
376 	target_desc = acpi_ns_get_attached_object(node);
377 
378 	ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Storing %p [%s] to node %p [%s]\n",
379 			  source_desc,
380 			  acpi_ut_get_object_type_name(source_desc), node,
381 			  acpi_ut_get_type_name(target_type)));
382 
383 	/* Only limited target types possible for everything except copy_object */
384 
385 	if (walk_state->opcode != AML_COPY_OBJECT_OP) {
386 		/*
387 		 * Only copy_object allows all object types to be overwritten. For
388 		 * target_ref(s), there are restrictions on the object types that
389 		 * are allowed.
390 		 *
391 		 * Allowable operations/typing for Store:
392 		 *
393 		 * 1) Simple Store
394 		 *      Integer     --> Integer (Named/Local/Arg)
395 		 *      String      --> String  (Named/Local/Arg)
396 		 *      Buffer      --> Buffer  (Named/Local/Arg)
397 		 *      Package     --> Package (Named/Local/Arg)
398 		 *
399 		 * 2) Store with implicit conversion
400 		 *      Integer     --> String or Buffer  (Named)
401 		 *      String      --> Integer or Buffer (Named)
402 		 *      Buffer      --> Integer or String (Named)
403 		 */
404 		switch (target_type) {
405 		case ACPI_TYPE_PACKAGE:
406 			/*
407 			 * Here, can only store a package to an existing package.
408 			 * Storing a package to a Local/Arg is OK, and handled
409 			 * elsewhere.
410 			 */
411 			if (walk_state->opcode == AML_STORE_OP) {
412 				if (source_desc->common.type !=
413 				    ACPI_TYPE_PACKAGE) {
414 					ACPI_ERROR((AE_INFO,
415 						    "Cannot assign type [%s] to [Package] "
416 						    "(source must be type Pkg)",
417 						    acpi_ut_get_object_type_name
418 						    (source_desc)));
419 
420 					return_ACPI_STATUS(AE_AML_TARGET_TYPE);
421 				}
422 				break;
423 			}
424 
425 			ACPI_FALLTHROUGH;
426 
427 		case ACPI_TYPE_DEVICE:
428 		case ACPI_TYPE_EVENT:
429 		case ACPI_TYPE_MUTEX:
430 		case ACPI_TYPE_REGION:
431 		case ACPI_TYPE_POWER:
432 		case ACPI_TYPE_PROCESSOR:
433 		case ACPI_TYPE_THERMAL:
434 
435 			ACPI_ERROR((AE_INFO,
436 				    "Target must be [Buffer/Integer/String/Reference]"
437 				    ", found [%s] (%4.4s)",
438 				    acpi_ut_get_type_name(node->type),
439 				    node->name.ascii));
440 
441 			return_ACPI_STATUS(AE_AML_TARGET_TYPE);
442 
443 		default:
444 			break;
445 		}
446 	}
447 
448 	/*
449 	 * Resolve the source object to an actual value
450 	 * (If it is a reference object)
451 	 */
452 	status = acpi_ex_resolve_object(&source_desc, target_type, walk_state);
453 	if (ACPI_FAILURE(status)) {
454 		return_ACPI_STATUS(status);
455 	}
456 
457 	/* Do the actual store operation */
458 
459 	switch (target_type) {
460 		/*
461 		 * The simple data types all support implicit source operand
462 		 * conversion before the store.
463 		 */
464 	case ACPI_TYPE_INTEGER:
465 	case ACPI_TYPE_STRING:
466 	case ACPI_TYPE_BUFFER:
467 
468 		if ((walk_state->opcode == AML_COPY_OBJECT_OP) ||
469 		    !implicit_conversion) {
470 			/*
471 			 * However, copy_object and Stores to arg_x do not perform
472 			 * an implicit conversion, as per the ACPI specification.
473 			 * A direct store is performed instead.
474 			 */
475 			status =
476 			    acpi_ex_store_direct_to_node(source_desc, node,
477 							 walk_state);
478 			break;
479 		}
480 
481 		/* Store with implicit source operand conversion support */
482 
483 		status =
484 		    acpi_ex_store_object_to_object(source_desc, target_desc,
485 						   &new_desc, walk_state);
486 		if (ACPI_FAILURE(status)) {
487 			return_ACPI_STATUS(status);
488 		}
489 
490 		if (new_desc != target_desc) {
491 			/*
492 			 * Store the new new_desc as the new value of the Name, and set
493 			 * the Name's type to that of the value being stored in it.
494 			 * source_desc reference count is incremented by attach_object.
495 			 *
496 			 * Note: This may change the type of the node if an explicit
497 			 * store has been performed such that the node/object type
498 			 * has been changed.
499 			 */
500 			status =
501 			    acpi_ns_attach_object(node, new_desc,
502 						  new_desc->common.type);
503 
504 			ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
505 					  "Store type [%s] into [%s] via Convert/Attach\n",
506 					  acpi_ut_get_object_type_name
507 					  (source_desc),
508 					  acpi_ut_get_object_type_name
509 					  (new_desc)));
510 		}
511 		break;
512 
513 	case ACPI_TYPE_BUFFER_FIELD:
514 	case ACPI_TYPE_LOCAL_REGION_FIELD:
515 	case ACPI_TYPE_LOCAL_BANK_FIELD:
516 	case ACPI_TYPE_LOCAL_INDEX_FIELD:
517 		/*
518 		 * For all fields, always write the source data to the target
519 		 * field. Any required implicit source operand conversion is
520 		 * performed in the function below as necessary. Note, field
521 		 * objects must retain their original type permanently.
522 		 */
523 		status = acpi_ex_write_data_to_field(source_desc, target_desc,
524 						     &walk_state->result_obj);
525 		break;
526 
527 	default:
528 		/*
529 		 * copy_object operator: No conversions for all other types.
530 		 * Instead, directly store a copy of the source object.
531 		 *
532 		 * This is the ACPI spec-defined behavior for the copy_object
533 		 * operator. (Note, for this default case, all normal
534 		 * Store/Target operations exited above with an error).
535 		 */
536 		status =
537 		    acpi_ex_store_direct_to_node(source_desc, node, walk_state);
538 		break;
539 	}
540 
541 	return_ACPI_STATUS(status);
542 }
543 
544 /*******************************************************************************
545  *
546  * FUNCTION:    acpi_ex_store_direct_to_node
547  *
548  * PARAMETERS:  source_desc             - Value to be stored
549  *              node                    - Named object to receive the value
550  *              walk_state              - Current walk state
551  *
552  * RETURN:      Status
553  *
554  * DESCRIPTION: "Store" an object directly to a node. This involves a copy
555  *              and an attach.
556  *
557  ******************************************************************************/
558 
559 static acpi_status
acpi_ex_store_direct_to_node(union acpi_operand_object * source_desc,struct acpi_namespace_node * node,struct acpi_walk_state * walk_state)560 acpi_ex_store_direct_to_node(union acpi_operand_object *source_desc,
561 			     struct acpi_namespace_node *node,
562 			     struct acpi_walk_state *walk_state)
563 {
564 	acpi_status status;
565 	union acpi_operand_object *new_desc;
566 
567 	ACPI_FUNCTION_TRACE(ex_store_direct_to_node);
568 
569 	ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
570 			  "Storing [%s] (%p) directly into node [%s] (%p)"
571 			  " with no implicit conversion\n",
572 			  acpi_ut_get_object_type_name(source_desc),
573 			  source_desc, acpi_ut_get_type_name(node->type),
574 			  node));
575 
576 	/* Copy the source object to a new object */
577 
578 	status =
579 	    acpi_ut_copy_iobject_to_iobject(source_desc, &new_desc, walk_state);
580 	if (ACPI_FAILURE(status)) {
581 		return_ACPI_STATUS(status);
582 	}
583 
584 	/* Attach the new object to the node */
585 
586 	status = acpi_ns_attach_object(node, new_desc, new_desc->common.type);
587 	acpi_ut_remove_reference(new_desc);
588 	return_ACPI_STATUS(status);
589 }
590