xref: /OK3568_Linux_fs/kernel/drivers/acpi/acpica/dsopcode.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
2*4882a593Smuzhiyun /******************************************************************************
3*4882a593Smuzhiyun  *
4*4882a593Smuzhiyun  * Module Name: dsopcode - Dispatcher support for regions and fields
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 "acparser.h"
13*4882a593Smuzhiyun #include "amlcode.h"
14*4882a593Smuzhiyun #include "acdispat.h"
15*4882a593Smuzhiyun #include "acinterp.h"
16*4882a593Smuzhiyun #include "acnamesp.h"
17*4882a593Smuzhiyun #include "acevents.h"
18*4882a593Smuzhiyun #include "actables.h"
19*4882a593Smuzhiyun 
20*4882a593Smuzhiyun #define _COMPONENT          ACPI_DISPATCHER
21*4882a593Smuzhiyun ACPI_MODULE_NAME("dsopcode")
22*4882a593Smuzhiyun 
23*4882a593Smuzhiyun /* Local prototypes */
24*4882a593Smuzhiyun static acpi_status
25*4882a593Smuzhiyun acpi_ds_init_buffer_field(u16 aml_opcode,
26*4882a593Smuzhiyun 			  union acpi_operand_object *obj_desc,
27*4882a593Smuzhiyun 			  union acpi_operand_object *buffer_desc,
28*4882a593Smuzhiyun 			  union acpi_operand_object *offset_desc,
29*4882a593Smuzhiyun 			  union acpi_operand_object *length_desc,
30*4882a593Smuzhiyun 			  union acpi_operand_object *result_desc);
31*4882a593Smuzhiyun 
32*4882a593Smuzhiyun /*******************************************************************************
33*4882a593Smuzhiyun  *
34*4882a593Smuzhiyun  * FUNCTION:    acpi_ds_initialize_region
35*4882a593Smuzhiyun  *
36*4882a593Smuzhiyun  * PARAMETERS:  obj_handle      - Region namespace node
37*4882a593Smuzhiyun  *
38*4882a593Smuzhiyun  * RETURN:      Status
39*4882a593Smuzhiyun  *
40*4882a593Smuzhiyun  * DESCRIPTION: Front end to ev_initialize_region
41*4882a593Smuzhiyun  *
42*4882a593Smuzhiyun  ******************************************************************************/
43*4882a593Smuzhiyun 
acpi_ds_initialize_region(acpi_handle obj_handle)44*4882a593Smuzhiyun acpi_status acpi_ds_initialize_region(acpi_handle obj_handle)
45*4882a593Smuzhiyun {
46*4882a593Smuzhiyun 	union acpi_operand_object *obj_desc;
47*4882a593Smuzhiyun 	acpi_status status;
48*4882a593Smuzhiyun 
49*4882a593Smuzhiyun 	obj_desc = acpi_ns_get_attached_object(obj_handle);
50*4882a593Smuzhiyun 
51*4882a593Smuzhiyun 	/* Namespace is NOT locked */
52*4882a593Smuzhiyun 
53*4882a593Smuzhiyun 	status = acpi_ev_initialize_region(obj_desc);
54*4882a593Smuzhiyun 	return (status);
55*4882a593Smuzhiyun }
56*4882a593Smuzhiyun 
57*4882a593Smuzhiyun /*******************************************************************************
58*4882a593Smuzhiyun  *
59*4882a593Smuzhiyun  * FUNCTION:    acpi_ds_init_buffer_field
60*4882a593Smuzhiyun  *
61*4882a593Smuzhiyun  * PARAMETERS:  aml_opcode      - create_xxx_field
62*4882a593Smuzhiyun  *              obj_desc        - buffer_field object
63*4882a593Smuzhiyun  *              buffer_desc     - Host Buffer
64*4882a593Smuzhiyun  *              offset_desc     - Offset into buffer
65*4882a593Smuzhiyun  *              length_desc     - Length of field (CREATE_FIELD_OP only)
66*4882a593Smuzhiyun  *              result_desc     - Where to store the result
67*4882a593Smuzhiyun  *
68*4882a593Smuzhiyun  * RETURN:      Status
69*4882a593Smuzhiyun  *
70*4882a593Smuzhiyun  * DESCRIPTION: Perform actual initialization of a buffer field
71*4882a593Smuzhiyun  *
72*4882a593Smuzhiyun  ******************************************************************************/
73*4882a593Smuzhiyun 
74*4882a593Smuzhiyun static acpi_status
acpi_ds_init_buffer_field(u16 aml_opcode,union acpi_operand_object * obj_desc,union acpi_operand_object * buffer_desc,union acpi_operand_object * offset_desc,union acpi_operand_object * length_desc,union acpi_operand_object * result_desc)75*4882a593Smuzhiyun acpi_ds_init_buffer_field(u16 aml_opcode,
76*4882a593Smuzhiyun 			  union acpi_operand_object *obj_desc,
77*4882a593Smuzhiyun 			  union acpi_operand_object *buffer_desc,
78*4882a593Smuzhiyun 			  union acpi_operand_object *offset_desc,
79*4882a593Smuzhiyun 			  union acpi_operand_object *length_desc,
80*4882a593Smuzhiyun 			  union acpi_operand_object *result_desc)
81*4882a593Smuzhiyun {
82*4882a593Smuzhiyun 	u32 offset;
83*4882a593Smuzhiyun 	u32 bit_offset;
84*4882a593Smuzhiyun 	u32 bit_count;
85*4882a593Smuzhiyun 	u8 field_flags;
86*4882a593Smuzhiyun 	acpi_status status;
87*4882a593Smuzhiyun 
88*4882a593Smuzhiyun 	ACPI_FUNCTION_TRACE_PTR(ds_init_buffer_field, obj_desc);
89*4882a593Smuzhiyun 
90*4882a593Smuzhiyun 	/* Host object must be a Buffer */
91*4882a593Smuzhiyun 
92*4882a593Smuzhiyun 	if (buffer_desc->common.type != ACPI_TYPE_BUFFER) {
93*4882a593Smuzhiyun 		ACPI_ERROR((AE_INFO,
94*4882a593Smuzhiyun 			    "Target of Create Field is not a Buffer object - %s",
95*4882a593Smuzhiyun 			    acpi_ut_get_object_type_name(buffer_desc)));
96*4882a593Smuzhiyun 
97*4882a593Smuzhiyun 		status = AE_AML_OPERAND_TYPE;
98*4882a593Smuzhiyun 		goto cleanup;
99*4882a593Smuzhiyun 	}
100*4882a593Smuzhiyun 
101*4882a593Smuzhiyun 	/*
102*4882a593Smuzhiyun 	 * The last parameter to all of these opcodes (result_desc) started
103*4882a593Smuzhiyun 	 * out as a name_string, and should therefore now be a NS node
104*4882a593Smuzhiyun 	 * after resolution in acpi_ex_resolve_operands().
105*4882a593Smuzhiyun 	 */
106*4882a593Smuzhiyun 	if (ACPI_GET_DESCRIPTOR_TYPE(result_desc) != ACPI_DESC_TYPE_NAMED) {
107*4882a593Smuzhiyun 		ACPI_ERROR((AE_INFO,
108*4882a593Smuzhiyun 			    "(%s) destination not a NS Node [%s]",
109*4882a593Smuzhiyun 			    acpi_ps_get_opcode_name(aml_opcode),
110*4882a593Smuzhiyun 			    acpi_ut_get_descriptor_name(result_desc)));
111*4882a593Smuzhiyun 
112*4882a593Smuzhiyun 		status = AE_AML_OPERAND_TYPE;
113*4882a593Smuzhiyun 		goto cleanup;
114*4882a593Smuzhiyun 	}
115*4882a593Smuzhiyun 
116*4882a593Smuzhiyun 	offset = (u32) offset_desc->integer.value;
117*4882a593Smuzhiyun 
118*4882a593Smuzhiyun 	/*
119*4882a593Smuzhiyun 	 * Setup the Bit offsets and counts, according to the opcode
120*4882a593Smuzhiyun 	 */
121*4882a593Smuzhiyun 	switch (aml_opcode) {
122*4882a593Smuzhiyun 	case AML_CREATE_FIELD_OP:
123*4882a593Smuzhiyun 
124*4882a593Smuzhiyun 		/* Offset is in bits, count is in bits */
125*4882a593Smuzhiyun 
126*4882a593Smuzhiyun 		field_flags = AML_FIELD_ACCESS_BYTE;
127*4882a593Smuzhiyun 		bit_offset = offset;
128*4882a593Smuzhiyun 		bit_count = (u32) length_desc->integer.value;
129*4882a593Smuzhiyun 
130*4882a593Smuzhiyun 		/* Must have a valid (>0) bit count */
131*4882a593Smuzhiyun 
132*4882a593Smuzhiyun 		if (bit_count == 0) {
133*4882a593Smuzhiyun 			ACPI_BIOS_ERROR((AE_INFO,
134*4882a593Smuzhiyun 					 "Attempt to CreateField of length zero"));
135*4882a593Smuzhiyun 			status = AE_AML_OPERAND_VALUE;
136*4882a593Smuzhiyun 			goto cleanup;
137*4882a593Smuzhiyun 		}
138*4882a593Smuzhiyun 		break;
139*4882a593Smuzhiyun 
140*4882a593Smuzhiyun 	case AML_CREATE_BIT_FIELD_OP:
141*4882a593Smuzhiyun 
142*4882a593Smuzhiyun 		/* Offset is in bits, Field is one bit */
143*4882a593Smuzhiyun 
144*4882a593Smuzhiyun 		bit_offset = offset;
145*4882a593Smuzhiyun 		bit_count = 1;
146*4882a593Smuzhiyun 		field_flags = AML_FIELD_ACCESS_BYTE;
147*4882a593Smuzhiyun 		break;
148*4882a593Smuzhiyun 
149*4882a593Smuzhiyun 	case AML_CREATE_BYTE_FIELD_OP:
150*4882a593Smuzhiyun 
151*4882a593Smuzhiyun 		/* Offset is in bytes, field is one byte */
152*4882a593Smuzhiyun 
153*4882a593Smuzhiyun 		bit_offset = 8 * offset;
154*4882a593Smuzhiyun 		bit_count = 8;
155*4882a593Smuzhiyun 		field_flags = AML_FIELD_ACCESS_BYTE;
156*4882a593Smuzhiyun 		break;
157*4882a593Smuzhiyun 
158*4882a593Smuzhiyun 	case AML_CREATE_WORD_FIELD_OP:
159*4882a593Smuzhiyun 
160*4882a593Smuzhiyun 		/* Offset is in bytes, field is one word */
161*4882a593Smuzhiyun 
162*4882a593Smuzhiyun 		bit_offset = 8 * offset;
163*4882a593Smuzhiyun 		bit_count = 16;
164*4882a593Smuzhiyun 		field_flags = AML_FIELD_ACCESS_WORD;
165*4882a593Smuzhiyun 		break;
166*4882a593Smuzhiyun 
167*4882a593Smuzhiyun 	case AML_CREATE_DWORD_FIELD_OP:
168*4882a593Smuzhiyun 
169*4882a593Smuzhiyun 		/* Offset is in bytes, field is one dword */
170*4882a593Smuzhiyun 
171*4882a593Smuzhiyun 		bit_offset = 8 * offset;
172*4882a593Smuzhiyun 		bit_count = 32;
173*4882a593Smuzhiyun 		field_flags = AML_FIELD_ACCESS_DWORD;
174*4882a593Smuzhiyun 		break;
175*4882a593Smuzhiyun 
176*4882a593Smuzhiyun 	case AML_CREATE_QWORD_FIELD_OP:
177*4882a593Smuzhiyun 
178*4882a593Smuzhiyun 		/* Offset is in bytes, field is one qword */
179*4882a593Smuzhiyun 
180*4882a593Smuzhiyun 		bit_offset = 8 * offset;
181*4882a593Smuzhiyun 		bit_count = 64;
182*4882a593Smuzhiyun 		field_flags = AML_FIELD_ACCESS_QWORD;
183*4882a593Smuzhiyun 		break;
184*4882a593Smuzhiyun 
185*4882a593Smuzhiyun 	default:
186*4882a593Smuzhiyun 
187*4882a593Smuzhiyun 		ACPI_ERROR((AE_INFO,
188*4882a593Smuzhiyun 			    "Unknown field creation opcode 0x%02X",
189*4882a593Smuzhiyun 			    aml_opcode));
190*4882a593Smuzhiyun 		status = AE_AML_BAD_OPCODE;
191*4882a593Smuzhiyun 		goto cleanup;
192*4882a593Smuzhiyun 	}
193*4882a593Smuzhiyun 
194*4882a593Smuzhiyun 	/* Entire field must fit within the current length of the buffer */
195*4882a593Smuzhiyun 
196*4882a593Smuzhiyun 	if ((bit_offset + bit_count) > (8 * (u32)buffer_desc->buffer.length)) {
197*4882a593Smuzhiyun 		status = AE_AML_BUFFER_LIMIT;
198*4882a593Smuzhiyun 		ACPI_BIOS_EXCEPTION((AE_INFO, status,
199*4882a593Smuzhiyun 				     "Field [%4.4s] at bit offset/length %u/%u "
200*4882a593Smuzhiyun 				     "exceeds size of target Buffer (%u bits)",
201*4882a593Smuzhiyun 				     acpi_ut_get_node_name(result_desc),
202*4882a593Smuzhiyun 				     bit_offset, bit_count,
203*4882a593Smuzhiyun 				     8 * (u32)buffer_desc->buffer.length));
204*4882a593Smuzhiyun 		goto cleanup;
205*4882a593Smuzhiyun 	}
206*4882a593Smuzhiyun 
207*4882a593Smuzhiyun 	/*
208*4882a593Smuzhiyun 	 * Initialize areas of the field object that are common to all fields
209*4882a593Smuzhiyun 	 * For field_flags, use LOCK_RULE = 0 (NO_LOCK),
210*4882a593Smuzhiyun 	 * UPDATE_RULE = 0 (UPDATE_PRESERVE)
211*4882a593Smuzhiyun 	 */
212*4882a593Smuzhiyun 	status =
213*4882a593Smuzhiyun 	    acpi_ex_prep_common_field_object(obj_desc, field_flags, 0,
214*4882a593Smuzhiyun 					     bit_offset, bit_count);
215*4882a593Smuzhiyun 	if (ACPI_FAILURE(status)) {
216*4882a593Smuzhiyun 		goto cleanup;
217*4882a593Smuzhiyun 	}
218*4882a593Smuzhiyun 
219*4882a593Smuzhiyun 	obj_desc->buffer_field.buffer_obj = buffer_desc;
220*4882a593Smuzhiyun 	obj_desc->buffer_field.is_create_field =
221*4882a593Smuzhiyun 	    aml_opcode == AML_CREATE_FIELD_OP;
222*4882a593Smuzhiyun 
223*4882a593Smuzhiyun 	/* Reference count for buffer_desc inherits obj_desc count */
224*4882a593Smuzhiyun 
225*4882a593Smuzhiyun 	buffer_desc->common.reference_count = (u16)
226*4882a593Smuzhiyun 	    (buffer_desc->common.reference_count +
227*4882a593Smuzhiyun 	     obj_desc->common.reference_count);
228*4882a593Smuzhiyun 
229*4882a593Smuzhiyun cleanup:
230*4882a593Smuzhiyun 
231*4882a593Smuzhiyun 	/* Always delete the operands */
232*4882a593Smuzhiyun 
233*4882a593Smuzhiyun 	acpi_ut_remove_reference(offset_desc);
234*4882a593Smuzhiyun 	acpi_ut_remove_reference(buffer_desc);
235*4882a593Smuzhiyun 
236*4882a593Smuzhiyun 	if (aml_opcode == AML_CREATE_FIELD_OP) {
237*4882a593Smuzhiyun 		acpi_ut_remove_reference(length_desc);
238*4882a593Smuzhiyun 	}
239*4882a593Smuzhiyun 
240*4882a593Smuzhiyun 	/* On failure, delete the result descriptor */
241*4882a593Smuzhiyun 
242*4882a593Smuzhiyun 	if (ACPI_FAILURE(status)) {
243*4882a593Smuzhiyun 		acpi_ut_remove_reference(result_desc);	/* Result descriptor */
244*4882a593Smuzhiyun 	} else {
245*4882a593Smuzhiyun 		/* Now the address and length are valid for this buffer_field */
246*4882a593Smuzhiyun 
247*4882a593Smuzhiyun 		obj_desc->buffer_field.flags |= AOPOBJ_DATA_VALID;
248*4882a593Smuzhiyun 	}
249*4882a593Smuzhiyun 
250*4882a593Smuzhiyun 	return_ACPI_STATUS(status);
251*4882a593Smuzhiyun }
252*4882a593Smuzhiyun 
253*4882a593Smuzhiyun /*******************************************************************************
254*4882a593Smuzhiyun  *
255*4882a593Smuzhiyun  * FUNCTION:    acpi_ds_eval_buffer_field_operands
256*4882a593Smuzhiyun  *
257*4882a593Smuzhiyun  * PARAMETERS:  walk_state      - Current walk
258*4882a593Smuzhiyun  *              op              - A valid buffer_field Op object
259*4882a593Smuzhiyun  *
260*4882a593Smuzhiyun  * RETURN:      Status
261*4882a593Smuzhiyun  *
262*4882a593Smuzhiyun  * DESCRIPTION: Get buffer_field Buffer and Index
263*4882a593Smuzhiyun  *              Called from acpi_ds_exec_end_op during buffer_field parse tree walk
264*4882a593Smuzhiyun  *
265*4882a593Smuzhiyun  ******************************************************************************/
266*4882a593Smuzhiyun 
267*4882a593Smuzhiyun acpi_status
acpi_ds_eval_buffer_field_operands(struct acpi_walk_state * walk_state,union acpi_parse_object * op)268*4882a593Smuzhiyun acpi_ds_eval_buffer_field_operands(struct acpi_walk_state *walk_state,
269*4882a593Smuzhiyun 				   union acpi_parse_object *op)
270*4882a593Smuzhiyun {
271*4882a593Smuzhiyun 	acpi_status status;
272*4882a593Smuzhiyun 	union acpi_operand_object *obj_desc;
273*4882a593Smuzhiyun 	struct acpi_namespace_node *node;
274*4882a593Smuzhiyun 	union acpi_parse_object *next_op;
275*4882a593Smuzhiyun 
276*4882a593Smuzhiyun 	ACPI_FUNCTION_TRACE_PTR(ds_eval_buffer_field_operands, op);
277*4882a593Smuzhiyun 
278*4882a593Smuzhiyun 	/*
279*4882a593Smuzhiyun 	 * This is where we evaluate the address and length fields of the
280*4882a593Smuzhiyun 	 * create_xxx_field declaration
281*4882a593Smuzhiyun 	 */
282*4882a593Smuzhiyun 	node = op->common.node;
283*4882a593Smuzhiyun 
284*4882a593Smuzhiyun 	/* next_op points to the op that holds the Buffer */
285*4882a593Smuzhiyun 
286*4882a593Smuzhiyun 	next_op = op->common.value.arg;
287*4882a593Smuzhiyun 
288*4882a593Smuzhiyun 	/* Evaluate/create the address and length operands */
289*4882a593Smuzhiyun 
290*4882a593Smuzhiyun 	status = acpi_ds_create_operands(walk_state, next_op);
291*4882a593Smuzhiyun 	if (ACPI_FAILURE(status)) {
292*4882a593Smuzhiyun 		return_ACPI_STATUS(status);
293*4882a593Smuzhiyun 	}
294*4882a593Smuzhiyun 
295*4882a593Smuzhiyun 	obj_desc = acpi_ns_get_attached_object(node);
296*4882a593Smuzhiyun 	if (!obj_desc) {
297*4882a593Smuzhiyun 		return_ACPI_STATUS(AE_NOT_EXIST);
298*4882a593Smuzhiyun 	}
299*4882a593Smuzhiyun 
300*4882a593Smuzhiyun 	/* Resolve the operands */
301*4882a593Smuzhiyun 
302*4882a593Smuzhiyun 	status =
303*4882a593Smuzhiyun 	    acpi_ex_resolve_operands(op->common.aml_opcode, ACPI_WALK_OPERANDS,
304*4882a593Smuzhiyun 				     walk_state);
305*4882a593Smuzhiyun 	if (ACPI_FAILURE(status)) {
306*4882a593Smuzhiyun 		ACPI_ERROR((AE_INFO, "(%s) bad operand(s), status 0x%X",
307*4882a593Smuzhiyun 			    acpi_ps_get_opcode_name(op->common.aml_opcode),
308*4882a593Smuzhiyun 			    status));
309*4882a593Smuzhiyun 
310*4882a593Smuzhiyun 		return_ACPI_STATUS(status);
311*4882a593Smuzhiyun 	}
312*4882a593Smuzhiyun 
313*4882a593Smuzhiyun 	/* Initialize the Buffer Field */
314*4882a593Smuzhiyun 
315*4882a593Smuzhiyun 	if (op->common.aml_opcode == AML_CREATE_FIELD_OP) {
316*4882a593Smuzhiyun 
317*4882a593Smuzhiyun 		/* NOTE: Slightly different operands for this opcode */
318*4882a593Smuzhiyun 
319*4882a593Smuzhiyun 		status =
320*4882a593Smuzhiyun 		    acpi_ds_init_buffer_field(op->common.aml_opcode, obj_desc,
321*4882a593Smuzhiyun 					      walk_state->operands[0],
322*4882a593Smuzhiyun 					      walk_state->operands[1],
323*4882a593Smuzhiyun 					      walk_state->operands[2],
324*4882a593Smuzhiyun 					      walk_state->operands[3]);
325*4882a593Smuzhiyun 	} else {
326*4882a593Smuzhiyun 		/* All other, create_xxx_field opcodes */
327*4882a593Smuzhiyun 
328*4882a593Smuzhiyun 		status =
329*4882a593Smuzhiyun 		    acpi_ds_init_buffer_field(op->common.aml_opcode, obj_desc,
330*4882a593Smuzhiyun 					      walk_state->operands[0],
331*4882a593Smuzhiyun 					      walk_state->operands[1], NULL,
332*4882a593Smuzhiyun 					      walk_state->operands[2]);
333*4882a593Smuzhiyun 	}
334*4882a593Smuzhiyun 
335*4882a593Smuzhiyun 	return_ACPI_STATUS(status);
336*4882a593Smuzhiyun }
337*4882a593Smuzhiyun 
338*4882a593Smuzhiyun /*******************************************************************************
339*4882a593Smuzhiyun  *
340*4882a593Smuzhiyun  * FUNCTION:    acpi_ds_eval_region_operands
341*4882a593Smuzhiyun  *
342*4882a593Smuzhiyun  * PARAMETERS:  walk_state      - Current walk
343*4882a593Smuzhiyun  *              op              - A valid region Op object
344*4882a593Smuzhiyun  *
345*4882a593Smuzhiyun  * RETURN:      Status
346*4882a593Smuzhiyun  *
347*4882a593Smuzhiyun  * DESCRIPTION: Get region address and length
348*4882a593Smuzhiyun  *              Called from acpi_ds_exec_end_op during op_region parse tree walk
349*4882a593Smuzhiyun  *
350*4882a593Smuzhiyun  ******************************************************************************/
351*4882a593Smuzhiyun 
352*4882a593Smuzhiyun acpi_status
acpi_ds_eval_region_operands(struct acpi_walk_state * walk_state,union acpi_parse_object * op)353*4882a593Smuzhiyun acpi_ds_eval_region_operands(struct acpi_walk_state *walk_state,
354*4882a593Smuzhiyun 			     union acpi_parse_object *op)
355*4882a593Smuzhiyun {
356*4882a593Smuzhiyun 	acpi_status status;
357*4882a593Smuzhiyun 	union acpi_operand_object *obj_desc;
358*4882a593Smuzhiyun 	union acpi_operand_object *operand_desc;
359*4882a593Smuzhiyun 	struct acpi_namespace_node *node;
360*4882a593Smuzhiyun 	union acpi_parse_object *next_op;
361*4882a593Smuzhiyun 	acpi_adr_space_type space_id;
362*4882a593Smuzhiyun 
363*4882a593Smuzhiyun 	ACPI_FUNCTION_TRACE_PTR(ds_eval_region_operands, op);
364*4882a593Smuzhiyun 
365*4882a593Smuzhiyun 	/*
366*4882a593Smuzhiyun 	 * This is where we evaluate the address and length fields of the
367*4882a593Smuzhiyun 	 * op_region declaration
368*4882a593Smuzhiyun 	 */
369*4882a593Smuzhiyun 	node = op->common.node;
370*4882a593Smuzhiyun 
371*4882a593Smuzhiyun 	/* next_op points to the op that holds the space_ID */
372*4882a593Smuzhiyun 
373*4882a593Smuzhiyun 	next_op = op->common.value.arg;
374*4882a593Smuzhiyun 	space_id = (acpi_adr_space_type)next_op->common.value.integer;
375*4882a593Smuzhiyun 
376*4882a593Smuzhiyun 	/* next_op points to address op */
377*4882a593Smuzhiyun 
378*4882a593Smuzhiyun 	next_op = next_op->common.next;
379*4882a593Smuzhiyun 
380*4882a593Smuzhiyun 	/* Evaluate/create the address and length operands */
381*4882a593Smuzhiyun 
382*4882a593Smuzhiyun 	status = acpi_ds_create_operands(walk_state, next_op);
383*4882a593Smuzhiyun 	if (ACPI_FAILURE(status)) {
384*4882a593Smuzhiyun 		return_ACPI_STATUS(status);
385*4882a593Smuzhiyun 	}
386*4882a593Smuzhiyun 
387*4882a593Smuzhiyun 	/* Resolve the length and address operands to numbers */
388*4882a593Smuzhiyun 
389*4882a593Smuzhiyun 	status =
390*4882a593Smuzhiyun 	    acpi_ex_resolve_operands(op->common.aml_opcode, ACPI_WALK_OPERANDS,
391*4882a593Smuzhiyun 				     walk_state);
392*4882a593Smuzhiyun 	if (ACPI_FAILURE(status)) {
393*4882a593Smuzhiyun 		return_ACPI_STATUS(status);
394*4882a593Smuzhiyun 	}
395*4882a593Smuzhiyun 
396*4882a593Smuzhiyun 	obj_desc = acpi_ns_get_attached_object(node);
397*4882a593Smuzhiyun 	if (!obj_desc) {
398*4882a593Smuzhiyun 		return_ACPI_STATUS(AE_NOT_EXIST);
399*4882a593Smuzhiyun 	}
400*4882a593Smuzhiyun 
401*4882a593Smuzhiyun 	/*
402*4882a593Smuzhiyun 	 * Get the length operand and save it
403*4882a593Smuzhiyun 	 * (at Top of stack)
404*4882a593Smuzhiyun 	 */
405*4882a593Smuzhiyun 	operand_desc = walk_state->operands[walk_state->num_operands - 1];
406*4882a593Smuzhiyun 
407*4882a593Smuzhiyun 	obj_desc->region.length = (u32) operand_desc->integer.value;
408*4882a593Smuzhiyun 	acpi_ut_remove_reference(operand_desc);
409*4882a593Smuzhiyun 
410*4882a593Smuzhiyun 	/* A zero-length operation region is unusable. Just warn */
411*4882a593Smuzhiyun 
412*4882a593Smuzhiyun 	if (!obj_desc->region.length
413*4882a593Smuzhiyun 	    && (space_id < ACPI_NUM_PREDEFINED_REGIONS)) {
414*4882a593Smuzhiyun 		ACPI_WARNING((AE_INFO,
415*4882a593Smuzhiyun 			      "Operation Region [%4.4s] has zero length (SpaceId %X)",
416*4882a593Smuzhiyun 			      node->name.ascii, space_id));
417*4882a593Smuzhiyun 	}
418*4882a593Smuzhiyun 
419*4882a593Smuzhiyun 	/*
420*4882a593Smuzhiyun 	 * Get the address and save it
421*4882a593Smuzhiyun 	 * (at top of stack - 1)
422*4882a593Smuzhiyun 	 */
423*4882a593Smuzhiyun 	operand_desc = walk_state->operands[walk_state->num_operands - 2];
424*4882a593Smuzhiyun 
425*4882a593Smuzhiyun 	obj_desc->region.address = (acpi_physical_address)
426*4882a593Smuzhiyun 	    operand_desc->integer.value;
427*4882a593Smuzhiyun 	acpi_ut_remove_reference(operand_desc);
428*4882a593Smuzhiyun 
429*4882a593Smuzhiyun 	ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "RgnObj %p Addr %8.8X%8.8X Len %X\n",
430*4882a593Smuzhiyun 			  obj_desc,
431*4882a593Smuzhiyun 			  ACPI_FORMAT_UINT64(obj_desc->region.address),
432*4882a593Smuzhiyun 			  obj_desc->region.length));
433*4882a593Smuzhiyun 
434*4882a593Smuzhiyun 	status = acpi_ut_add_address_range(obj_desc->region.space_id,
435*4882a593Smuzhiyun 					   obj_desc->region.address,
436*4882a593Smuzhiyun 					   obj_desc->region.length, node);
437*4882a593Smuzhiyun 
438*4882a593Smuzhiyun 	/* Now the address and length are valid for this opregion */
439*4882a593Smuzhiyun 
440*4882a593Smuzhiyun 	obj_desc->region.flags |= AOPOBJ_DATA_VALID;
441*4882a593Smuzhiyun 	return_ACPI_STATUS(status);
442*4882a593Smuzhiyun }
443*4882a593Smuzhiyun 
444*4882a593Smuzhiyun /*******************************************************************************
445*4882a593Smuzhiyun  *
446*4882a593Smuzhiyun  * FUNCTION:    acpi_ds_eval_table_region_operands
447*4882a593Smuzhiyun  *
448*4882a593Smuzhiyun  * PARAMETERS:  walk_state      - Current walk
449*4882a593Smuzhiyun  *              op              - A valid region Op object
450*4882a593Smuzhiyun  *
451*4882a593Smuzhiyun  * RETURN:      Status
452*4882a593Smuzhiyun  *
453*4882a593Smuzhiyun  * DESCRIPTION: Get region address and length.
454*4882a593Smuzhiyun  *              Called from acpi_ds_exec_end_op during data_table_region parse
455*4882a593Smuzhiyun  *              tree walk.
456*4882a593Smuzhiyun  *
457*4882a593Smuzhiyun  ******************************************************************************/
458*4882a593Smuzhiyun 
459*4882a593Smuzhiyun acpi_status
acpi_ds_eval_table_region_operands(struct acpi_walk_state * walk_state,union acpi_parse_object * op)460*4882a593Smuzhiyun acpi_ds_eval_table_region_operands(struct acpi_walk_state *walk_state,
461*4882a593Smuzhiyun 				   union acpi_parse_object *op)
462*4882a593Smuzhiyun {
463*4882a593Smuzhiyun 	acpi_status status;
464*4882a593Smuzhiyun 	union acpi_operand_object *obj_desc;
465*4882a593Smuzhiyun 	union acpi_operand_object **operand;
466*4882a593Smuzhiyun 	struct acpi_namespace_node *node;
467*4882a593Smuzhiyun 	union acpi_parse_object *next_op;
468*4882a593Smuzhiyun 	struct acpi_table_header *table;
469*4882a593Smuzhiyun 	u32 table_index;
470*4882a593Smuzhiyun 
471*4882a593Smuzhiyun 	ACPI_FUNCTION_TRACE_PTR(ds_eval_table_region_operands, op);
472*4882a593Smuzhiyun 
473*4882a593Smuzhiyun 	/*
474*4882a593Smuzhiyun 	 * This is where we evaluate the Signature string, oem_id string,
475*4882a593Smuzhiyun 	 * and oem_table_id string of the Data Table Region declaration
476*4882a593Smuzhiyun 	 */
477*4882a593Smuzhiyun 	node = op->common.node;
478*4882a593Smuzhiyun 
479*4882a593Smuzhiyun 	/* next_op points to Signature string op */
480*4882a593Smuzhiyun 
481*4882a593Smuzhiyun 	next_op = op->common.value.arg;
482*4882a593Smuzhiyun 
483*4882a593Smuzhiyun 	/*
484*4882a593Smuzhiyun 	 * Evaluate/create the Signature string, oem_id string,
485*4882a593Smuzhiyun 	 * and oem_table_id string operands
486*4882a593Smuzhiyun 	 */
487*4882a593Smuzhiyun 	status = acpi_ds_create_operands(walk_state, next_op);
488*4882a593Smuzhiyun 	if (ACPI_FAILURE(status)) {
489*4882a593Smuzhiyun 		return_ACPI_STATUS(status);
490*4882a593Smuzhiyun 	}
491*4882a593Smuzhiyun 
492*4882a593Smuzhiyun 	operand = &walk_state->operands[0];
493*4882a593Smuzhiyun 
494*4882a593Smuzhiyun 	/*
495*4882a593Smuzhiyun 	 * Resolve the Signature string, oem_id string,
496*4882a593Smuzhiyun 	 * and oem_table_id string operands
497*4882a593Smuzhiyun 	 */
498*4882a593Smuzhiyun 	status =
499*4882a593Smuzhiyun 	    acpi_ex_resolve_operands(op->common.aml_opcode, ACPI_WALK_OPERANDS,
500*4882a593Smuzhiyun 				     walk_state);
501*4882a593Smuzhiyun 	if (ACPI_FAILURE(status)) {
502*4882a593Smuzhiyun 		goto cleanup;
503*4882a593Smuzhiyun 	}
504*4882a593Smuzhiyun 
505*4882a593Smuzhiyun 	/* Find the ACPI table */
506*4882a593Smuzhiyun 
507*4882a593Smuzhiyun 	status = acpi_tb_find_table(operand[0]->string.pointer,
508*4882a593Smuzhiyun 				    operand[1]->string.pointer,
509*4882a593Smuzhiyun 				    operand[2]->string.pointer, &table_index);
510*4882a593Smuzhiyun 	if (ACPI_FAILURE(status)) {
511*4882a593Smuzhiyun 		if (status == AE_NOT_FOUND) {
512*4882a593Smuzhiyun 			ACPI_ERROR((AE_INFO,
513*4882a593Smuzhiyun 				    "ACPI Table [%4.4s] OEM:(%s, %s) not found in RSDT/XSDT",
514*4882a593Smuzhiyun 				    operand[0]->string.pointer,
515*4882a593Smuzhiyun 				    operand[1]->string.pointer,
516*4882a593Smuzhiyun 				    operand[2]->string.pointer));
517*4882a593Smuzhiyun 		}
518*4882a593Smuzhiyun 		goto cleanup;
519*4882a593Smuzhiyun 	}
520*4882a593Smuzhiyun 
521*4882a593Smuzhiyun 	status = acpi_get_table_by_index(table_index, &table);
522*4882a593Smuzhiyun 	if (ACPI_FAILURE(status)) {
523*4882a593Smuzhiyun 		goto cleanup;
524*4882a593Smuzhiyun 	}
525*4882a593Smuzhiyun 
526*4882a593Smuzhiyun 	obj_desc = acpi_ns_get_attached_object(node);
527*4882a593Smuzhiyun 	if (!obj_desc) {
528*4882a593Smuzhiyun 		status = AE_NOT_EXIST;
529*4882a593Smuzhiyun 		goto cleanup;
530*4882a593Smuzhiyun 	}
531*4882a593Smuzhiyun 
532*4882a593Smuzhiyun 	obj_desc->region.address = ACPI_PTR_TO_PHYSADDR(table);
533*4882a593Smuzhiyun 	obj_desc->region.length = table->length;
534*4882a593Smuzhiyun 
535*4882a593Smuzhiyun 	ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "RgnObj %p Addr %8.8X%8.8X Len %X\n",
536*4882a593Smuzhiyun 			  obj_desc,
537*4882a593Smuzhiyun 			  ACPI_FORMAT_UINT64(obj_desc->region.address),
538*4882a593Smuzhiyun 			  obj_desc->region.length));
539*4882a593Smuzhiyun 
540*4882a593Smuzhiyun 	/* Now the address and length are valid for this opregion */
541*4882a593Smuzhiyun 
542*4882a593Smuzhiyun 	obj_desc->region.flags |= AOPOBJ_DATA_VALID;
543*4882a593Smuzhiyun 
544*4882a593Smuzhiyun cleanup:
545*4882a593Smuzhiyun 	acpi_ut_remove_reference(operand[0]);
546*4882a593Smuzhiyun 	acpi_ut_remove_reference(operand[1]);
547*4882a593Smuzhiyun 	acpi_ut_remove_reference(operand[2]);
548*4882a593Smuzhiyun 
549*4882a593Smuzhiyun 	return_ACPI_STATUS(status);
550*4882a593Smuzhiyun }
551*4882a593Smuzhiyun 
552*4882a593Smuzhiyun /*******************************************************************************
553*4882a593Smuzhiyun  *
554*4882a593Smuzhiyun  * FUNCTION:    acpi_ds_eval_data_object_operands
555*4882a593Smuzhiyun  *
556*4882a593Smuzhiyun  * PARAMETERS:  walk_state      - Current walk
557*4882a593Smuzhiyun  *              op              - A valid data_object Op object
558*4882a593Smuzhiyun  *              obj_desc        - data_object
559*4882a593Smuzhiyun  *
560*4882a593Smuzhiyun  * RETURN:      Status
561*4882a593Smuzhiyun  *
562*4882a593Smuzhiyun  * DESCRIPTION: Get the operands and complete the following data object types:
563*4882a593Smuzhiyun  *              Buffer, Package.
564*4882a593Smuzhiyun  *
565*4882a593Smuzhiyun  ******************************************************************************/
566*4882a593Smuzhiyun 
567*4882a593Smuzhiyun acpi_status
acpi_ds_eval_data_object_operands(struct acpi_walk_state * walk_state,union acpi_parse_object * op,union acpi_operand_object * obj_desc)568*4882a593Smuzhiyun acpi_ds_eval_data_object_operands(struct acpi_walk_state *walk_state,
569*4882a593Smuzhiyun 				  union acpi_parse_object *op,
570*4882a593Smuzhiyun 				  union acpi_operand_object *obj_desc)
571*4882a593Smuzhiyun {
572*4882a593Smuzhiyun 	acpi_status status;
573*4882a593Smuzhiyun 	union acpi_operand_object *arg_desc;
574*4882a593Smuzhiyun 	u32 length;
575*4882a593Smuzhiyun 
576*4882a593Smuzhiyun 	ACPI_FUNCTION_TRACE(ds_eval_data_object_operands);
577*4882a593Smuzhiyun 
578*4882a593Smuzhiyun 	/* The first operand (for all of these data objects) is the length */
579*4882a593Smuzhiyun 
580*4882a593Smuzhiyun 	/*
581*4882a593Smuzhiyun 	 * Set proper index into operand stack for acpi_ds_obj_stack_push
582*4882a593Smuzhiyun 	 * invoked inside acpi_ds_create_operand.
583*4882a593Smuzhiyun 	 */
584*4882a593Smuzhiyun 	walk_state->operand_index = walk_state->num_operands;
585*4882a593Smuzhiyun 
586*4882a593Smuzhiyun 	/* Ignore if child is not valid */
587*4882a593Smuzhiyun 
588*4882a593Smuzhiyun 	if (!op->common.value.arg) {
589*4882a593Smuzhiyun 		ACPI_ERROR((AE_INFO,
590*4882a593Smuzhiyun 			    "Missing child while evaluating opcode %4.4X, Op %p",
591*4882a593Smuzhiyun 			    op->common.aml_opcode, op));
592*4882a593Smuzhiyun 		return_ACPI_STATUS(AE_OK);
593*4882a593Smuzhiyun 	}
594*4882a593Smuzhiyun 
595*4882a593Smuzhiyun 	status = acpi_ds_create_operand(walk_state, op->common.value.arg, 1);
596*4882a593Smuzhiyun 	if (ACPI_FAILURE(status)) {
597*4882a593Smuzhiyun 		return_ACPI_STATUS(status);
598*4882a593Smuzhiyun 	}
599*4882a593Smuzhiyun 
600*4882a593Smuzhiyun 	status = acpi_ex_resolve_operands(walk_state->opcode,
601*4882a593Smuzhiyun 					  &(walk_state->
602*4882a593Smuzhiyun 					    operands[walk_state->num_operands -
603*4882a593Smuzhiyun 						     1]), walk_state);
604*4882a593Smuzhiyun 	if (ACPI_FAILURE(status)) {
605*4882a593Smuzhiyun 		return_ACPI_STATUS(status);
606*4882a593Smuzhiyun 	}
607*4882a593Smuzhiyun 
608*4882a593Smuzhiyun 	/* Extract length operand */
609*4882a593Smuzhiyun 
610*4882a593Smuzhiyun 	arg_desc = walk_state->operands[walk_state->num_operands - 1];
611*4882a593Smuzhiyun 	length = (u32) arg_desc->integer.value;
612*4882a593Smuzhiyun 
613*4882a593Smuzhiyun 	/* Cleanup for length operand */
614*4882a593Smuzhiyun 
615*4882a593Smuzhiyun 	status = acpi_ds_obj_stack_pop(1, walk_state);
616*4882a593Smuzhiyun 	if (ACPI_FAILURE(status)) {
617*4882a593Smuzhiyun 		return_ACPI_STATUS(status);
618*4882a593Smuzhiyun 	}
619*4882a593Smuzhiyun 
620*4882a593Smuzhiyun 	acpi_ut_remove_reference(arg_desc);
621*4882a593Smuzhiyun 
622*4882a593Smuzhiyun 	/*
623*4882a593Smuzhiyun 	 * Create the actual data object
624*4882a593Smuzhiyun 	 */
625*4882a593Smuzhiyun 	switch (op->common.aml_opcode) {
626*4882a593Smuzhiyun 	case AML_BUFFER_OP:
627*4882a593Smuzhiyun 
628*4882a593Smuzhiyun 		status =
629*4882a593Smuzhiyun 		    acpi_ds_build_internal_buffer_obj(walk_state, op, length,
630*4882a593Smuzhiyun 						      &obj_desc);
631*4882a593Smuzhiyun 		break;
632*4882a593Smuzhiyun 
633*4882a593Smuzhiyun 	case AML_PACKAGE_OP:
634*4882a593Smuzhiyun 	case AML_VARIABLE_PACKAGE_OP:
635*4882a593Smuzhiyun 
636*4882a593Smuzhiyun 		status =
637*4882a593Smuzhiyun 		    acpi_ds_build_internal_package_obj(walk_state, op, length,
638*4882a593Smuzhiyun 						       &obj_desc);
639*4882a593Smuzhiyun 		break;
640*4882a593Smuzhiyun 
641*4882a593Smuzhiyun 	default:
642*4882a593Smuzhiyun 
643*4882a593Smuzhiyun 		return_ACPI_STATUS(AE_AML_BAD_OPCODE);
644*4882a593Smuzhiyun 	}
645*4882a593Smuzhiyun 
646*4882a593Smuzhiyun 	if (ACPI_SUCCESS(status)) {
647*4882a593Smuzhiyun 		/*
648*4882a593Smuzhiyun 		 * Return the object in the walk_state, unless the parent is a package -
649*4882a593Smuzhiyun 		 * in this case, the return object will be stored in the parse tree
650*4882a593Smuzhiyun 		 * for the package.
651*4882a593Smuzhiyun 		 */
652*4882a593Smuzhiyun 		if ((!op->common.parent) ||
653*4882a593Smuzhiyun 		    ((op->common.parent->common.aml_opcode != AML_PACKAGE_OP) &&
654*4882a593Smuzhiyun 		     (op->common.parent->common.aml_opcode !=
655*4882a593Smuzhiyun 		      AML_VARIABLE_PACKAGE_OP)
656*4882a593Smuzhiyun 		     && (op->common.parent->common.aml_opcode !=
657*4882a593Smuzhiyun 			 AML_NAME_OP))) {
658*4882a593Smuzhiyun 			walk_state->result_obj = obj_desc;
659*4882a593Smuzhiyun 		}
660*4882a593Smuzhiyun 	}
661*4882a593Smuzhiyun 
662*4882a593Smuzhiyun 	return_ACPI_STATUS(status);
663*4882a593Smuzhiyun }
664*4882a593Smuzhiyun 
665*4882a593Smuzhiyun /*******************************************************************************
666*4882a593Smuzhiyun  *
667*4882a593Smuzhiyun  * FUNCTION:    acpi_ds_eval_bank_field_operands
668*4882a593Smuzhiyun  *
669*4882a593Smuzhiyun  * PARAMETERS:  walk_state      - Current walk
670*4882a593Smuzhiyun  *              op              - A valid bank_field Op object
671*4882a593Smuzhiyun  *
672*4882a593Smuzhiyun  * RETURN:      Status
673*4882a593Smuzhiyun  *
674*4882a593Smuzhiyun  * DESCRIPTION: Get bank_field bank_value
675*4882a593Smuzhiyun  *              Called from acpi_ds_exec_end_op during bank_field parse tree walk
676*4882a593Smuzhiyun  *
677*4882a593Smuzhiyun  ******************************************************************************/
678*4882a593Smuzhiyun 
679*4882a593Smuzhiyun acpi_status
acpi_ds_eval_bank_field_operands(struct acpi_walk_state * walk_state,union acpi_parse_object * op)680*4882a593Smuzhiyun acpi_ds_eval_bank_field_operands(struct acpi_walk_state *walk_state,
681*4882a593Smuzhiyun 				 union acpi_parse_object *op)
682*4882a593Smuzhiyun {
683*4882a593Smuzhiyun 	acpi_status status;
684*4882a593Smuzhiyun 	union acpi_operand_object *obj_desc;
685*4882a593Smuzhiyun 	union acpi_operand_object *operand_desc;
686*4882a593Smuzhiyun 	struct acpi_namespace_node *node;
687*4882a593Smuzhiyun 	union acpi_parse_object *next_op;
688*4882a593Smuzhiyun 	union acpi_parse_object *arg;
689*4882a593Smuzhiyun 
690*4882a593Smuzhiyun 	ACPI_FUNCTION_TRACE_PTR(ds_eval_bank_field_operands, op);
691*4882a593Smuzhiyun 
692*4882a593Smuzhiyun 	/*
693*4882a593Smuzhiyun 	 * This is where we evaluate the bank_value field of the
694*4882a593Smuzhiyun 	 * bank_field declaration
695*4882a593Smuzhiyun 	 */
696*4882a593Smuzhiyun 
697*4882a593Smuzhiyun 	/* next_op points to the op that holds the Region */
698*4882a593Smuzhiyun 
699*4882a593Smuzhiyun 	next_op = op->common.value.arg;
700*4882a593Smuzhiyun 
701*4882a593Smuzhiyun 	/* next_op points to the op that holds the Bank Register */
702*4882a593Smuzhiyun 
703*4882a593Smuzhiyun 	next_op = next_op->common.next;
704*4882a593Smuzhiyun 
705*4882a593Smuzhiyun 	/* next_op points to the op that holds the Bank Value */
706*4882a593Smuzhiyun 
707*4882a593Smuzhiyun 	next_op = next_op->common.next;
708*4882a593Smuzhiyun 
709*4882a593Smuzhiyun 	/*
710*4882a593Smuzhiyun 	 * Set proper index into operand stack for acpi_ds_obj_stack_push
711*4882a593Smuzhiyun 	 * invoked inside acpi_ds_create_operand.
712*4882a593Smuzhiyun 	 *
713*4882a593Smuzhiyun 	 * We use walk_state->Operands[0] to store the evaluated bank_value
714*4882a593Smuzhiyun 	 */
715*4882a593Smuzhiyun 	walk_state->operand_index = 0;
716*4882a593Smuzhiyun 
717*4882a593Smuzhiyun 	status = acpi_ds_create_operand(walk_state, next_op, 0);
718*4882a593Smuzhiyun 	if (ACPI_FAILURE(status)) {
719*4882a593Smuzhiyun 		return_ACPI_STATUS(status);
720*4882a593Smuzhiyun 	}
721*4882a593Smuzhiyun 
722*4882a593Smuzhiyun 	status = acpi_ex_resolve_to_value(&walk_state->operands[0], walk_state);
723*4882a593Smuzhiyun 	if (ACPI_FAILURE(status)) {
724*4882a593Smuzhiyun 		return_ACPI_STATUS(status);
725*4882a593Smuzhiyun 	}
726*4882a593Smuzhiyun 
727*4882a593Smuzhiyun 	ACPI_DUMP_OPERANDS(ACPI_WALK_OPERANDS,
728*4882a593Smuzhiyun 			   acpi_ps_get_opcode_name(op->common.aml_opcode), 1);
729*4882a593Smuzhiyun 	/*
730*4882a593Smuzhiyun 	 * Get the bank_value operand and save it
731*4882a593Smuzhiyun 	 * (at Top of stack)
732*4882a593Smuzhiyun 	 */
733*4882a593Smuzhiyun 	operand_desc = walk_state->operands[0];
734*4882a593Smuzhiyun 
735*4882a593Smuzhiyun 	/* Arg points to the start Bank Field */
736*4882a593Smuzhiyun 
737*4882a593Smuzhiyun 	arg = acpi_ps_get_arg(op, 4);
738*4882a593Smuzhiyun 	while (arg) {
739*4882a593Smuzhiyun 
740*4882a593Smuzhiyun 		/* Ignore OFFSET and ACCESSAS terms here */
741*4882a593Smuzhiyun 
742*4882a593Smuzhiyun 		if (arg->common.aml_opcode == AML_INT_NAMEDFIELD_OP) {
743*4882a593Smuzhiyun 			node = arg->common.node;
744*4882a593Smuzhiyun 
745*4882a593Smuzhiyun 			obj_desc = acpi_ns_get_attached_object(node);
746*4882a593Smuzhiyun 			if (!obj_desc) {
747*4882a593Smuzhiyun 				return_ACPI_STATUS(AE_NOT_EXIST);
748*4882a593Smuzhiyun 			}
749*4882a593Smuzhiyun 
750*4882a593Smuzhiyun 			obj_desc->bank_field.value =
751*4882a593Smuzhiyun 			    (u32) operand_desc->integer.value;
752*4882a593Smuzhiyun 		}
753*4882a593Smuzhiyun 
754*4882a593Smuzhiyun 		/* Move to next field in the list */
755*4882a593Smuzhiyun 
756*4882a593Smuzhiyun 		arg = arg->common.next;
757*4882a593Smuzhiyun 	}
758*4882a593Smuzhiyun 
759*4882a593Smuzhiyun 	acpi_ut_remove_reference(operand_desc);
760*4882a593Smuzhiyun 	return_ACPI_STATUS(status);
761*4882a593Smuzhiyun }
762