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