1*4882a593Smuzhiyun // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
2*4882a593Smuzhiyun /******************************************************************************
3*4882a593Smuzhiyun *
4*4882a593Smuzhiyun * Module Name: exresop - AML Interpreter operand/object resolution
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 "amlcode.h"
13*4882a593Smuzhiyun #include "acparser.h"
14*4882a593Smuzhiyun #include "acinterp.h"
15*4882a593Smuzhiyun #include "acnamesp.h"
16*4882a593Smuzhiyun
17*4882a593Smuzhiyun #define _COMPONENT ACPI_EXECUTER
18*4882a593Smuzhiyun ACPI_MODULE_NAME("exresop")
19*4882a593Smuzhiyun
20*4882a593Smuzhiyun /* Local prototypes */
21*4882a593Smuzhiyun static acpi_status
22*4882a593Smuzhiyun acpi_ex_check_object_type(acpi_object_type type_needed,
23*4882a593Smuzhiyun acpi_object_type this_type, void *object);
24*4882a593Smuzhiyun
25*4882a593Smuzhiyun /*******************************************************************************
26*4882a593Smuzhiyun *
27*4882a593Smuzhiyun * FUNCTION: acpi_ex_check_object_type
28*4882a593Smuzhiyun *
29*4882a593Smuzhiyun * PARAMETERS: type_needed Object type needed
30*4882a593Smuzhiyun * this_type Actual object type
31*4882a593Smuzhiyun * Object Object pointer
32*4882a593Smuzhiyun *
33*4882a593Smuzhiyun * RETURN: Status
34*4882a593Smuzhiyun *
35*4882a593Smuzhiyun * DESCRIPTION: Check required type against actual type
36*4882a593Smuzhiyun *
37*4882a593Smuzhiyun ******************************************************************************/
38*4882a593Smuzhiyun
39*4882a593Smuzhiyun static acpi_status
acpi_ex_check_object_type(acpi_object_type type_needed,acpi_object_type this_type,void * object)40*4882a593Smuzhiyun acpi_ex_check_object_type(acpi_object_type type_needed,
41*4882a593Smuzhiyun acpi_object_type this_type, void *object)
42*4882a593Smuzhiyun {
43*4882a593Smuzhiyun ACPI_FUNCTION_ENTRY();
44*4882a593Smuzhiyun
45*4882a593Smuzhiyun if (type_needed == ACPI_TYPE_ANY) {
46*4882a593Smuzhiyun
47*4882a593Smuzhiyun /* All types OK, so we don't perform any typechecks */
48*4882a593Smuzhiyun
49*4882a593Smuzhiyun return (AE_OK);
50*4882a593Smuzhiyun }
51*4882a593Smuzhiyun
52*4882a593Smuzhiyun if (type_needed == ACPI_TYPE_LOCAL_REFERENCE) {
53*4882a593Smuzhiyun /*
54*4882a593Smuzhiyun * Allow the AML "Constant" opcodes (Zero, One, etc.) to be reference
55*4882a593Smuzhiyun * objects and thus allow them to be targets. (As per the ACPI
56*4882a593Smuzhiyun * specification, a store to a constant is a noop.)
57*4882a593Smuzhiyun */
58*4882a593Smuzhiyun if ((this_type == ACPI_TYPE_INTEGER) &&
59*4882a593Smuzhiyun (((union acpi_operand_object *)object)->common.flags &
60*4882a593Smuzhiyun AOPOBJ_AML_CONSTANT)) {
61*4882a593Smuzhiyun return (AE_OK);
62*4882a593Smuzhiyun }
63*4882a593Smuzhiyun }
64*4882a593Smuzhiyun
65*4882a593Smuzhiyun if (type_needed != this_type) {
66*4882a593Smuzhiyun ACPI_ERROR((AE_INFO,
67*4882a593Smuzhiyun "Needed type [%s], found [%s] %p",
68*4882a593Smuzhiyun acpi_ut_get_type_name(type_needed),
69*4882a593Smuzhiyun acpi_ut_get_type_name(this_type), object));
70*4882a593Smuzhiyun
71*4882a593Smuzhiyun return (AE_AML_OPERAND_TYPE);
72*4882a593Smuzhiyun }
73*4882a593Smuzhiyun
74*4882a593Smuzhiyun return (AE_OK);
75*4882a593Smuzhiyun }
76*4882a593Smuzhiyun
77*4882a593Smuzhiyun /*******************************************************************************
78*4882a593Smuzhiyun *
79*4882a593Smuzhiyun * FUNCTION: acpi_ex_resolve_operands
80*4882a593Smuzhiyun *
81*4882a593Smuzhiyun * PARAMETERS: opcode - Opcode being interpreted
82*4882a593Smuzhiyun * stack_ptr - Pointer to the operand stack to be
83*4882a593Smuzhiyun * resolved
84*4882a593Smuzhiyun * walk_state - Current state
85*4882a593Smuzhiyun *
86*4882a593Smuzhiyun * RETURN: Status
87*4882a593Smuzhiyun *
88*4882a593Smuzhiyun * DESCRIPTION: Convert multiple input operands to the types required by the
89*4882a593Smuzhiyun * target operator.
90*4882a593Smuzhiyun *
91*4882a593Smuzhiyun * Each 5-bit group in arg_types represents one required
92*4882a593Smuzhiyun * operand and indicates the required Type. The corresponding operand
93*4882a593Smuzhiyun * will be converted to the required type if possible, otherwise we
94*4882a593Smuzhiyun * abort with an exception.
95*4882a593Smuzhiyun *
96*4882a593Smuzhiyun ******************************************************************************/
97*4882a593Smuzhiyun
98*4882a593Smuzhiyun acpi_status
acpi_ex_resolve_operands(u16 opcode,union acpi_operand_object ** stack_ptr,struct acpi_walk_state * walk_state)99*4882a593Smuzhiyun acpi_ex_resolve_operands(u16 opcode,
100*4882a593Smuzhiyun union acpi_operand_object **stack_ptr,
101*4882a593Smuzhiyun struct acpi_walk_state *walk_state)
102*4882a593Smuzhiyun {
103*4882a593Smuzhiyun union acpi_operand_object *obj_desc;
104*4882a593Smuzhiyun acpi_status status = AE_OK;
105*4882a593Smuzhiyun u8 object_type;
106*4882a593Smuzhiyun u32 arg_types;
107*4882a593Smuzhiyun const struct acpi_opcode_info *op_info;
108*4882a593Smuzhiyun u32 this_arg_type;
109*4882a593Smuzhiyun acpi_object_type type_needed;
110*4882a593Smuzhiyun u16 target_op = 0;
111*4882a593Smuzhiyun
112*4882a593Smuzhiyun ACPI_FUNCTION_TRACE_U32(ex_resolve_operands, opcode);
113*4882a593Smuzhiyun
114*4882a593Smuzhiyun op_info = acpi_ps_get_opcode_info(opcode);
115*4882a593Smuzhiyun if (op_info->class == AML_CLASS_UNKNOWN) {
116*4882a593Smuzhiyun return_ACPI_STATUS(AE_AML_BAD_OPCODE);
117*4882a593Smuzhiyun }
118*4882a593Smuzhiyun
119*4882a593Smuzhiyun arg_types = op_info->runtime_args;
120*4882a593Smuzhiyun if (arg_types == ARGI_INVALID_OPCODE) {
121*4882a593Smuzhiyun ACPI_ERROR((AE_INFO, "Unknown AML opcode 0x%X", opcode));
122*4882a593Smuzhiyun
123*4882a593Smuzhiyun return_ACPI_STATUS(AE_AML_INTERNAL);
124*4882a593Smuzhiyun }
125*4882a593Smuzhiyun
126*4882a593Smuzhiyun ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
127*4882a593Smuzhiyun "Opcode %X [%s] RequiredOperandTypes=%8.8X\n",
128*4882a593Smuzhiyun opcode, op_info->name, arg_types));
129*4882a593Smuzhiyun
130*4882a593Smuzhiyun /*
131*4882a593Smuzhiyun * Normal exit is with (arg_types == 0) at end of argument list.
132*4882a593Smuzhiyun * Function will return an exception from within the loop upon
133*4882a593Smuzhiyun * finding an entry which is not (or cannot be converted
134*4882a593Smuzhiyun * to) the required type; if stack underflows; or upon
135*4882a593Smuzhiyun * finding a NULL stack entry (which should not happen).
136*4882a593Smuzhiyun */
137*4882a593Smuzhiyun while (GET_CURRENT_ARG_TYPE(arg_types)) {
138*4882a593Smuzhiyun if (!stack_ptr || !*stack_ptr) {
139*4882a593Smuzhiyun ACPI_ERROR((AE_INFO, "Null stack entry at %p",
140*4882a593Smuzhiyun stack_ptr));
141*4882a593Smuzhiyun
142*4882a593Smuzhiyun return_ACPI_STATUS(AE_AML_INTERNAL);
143*4882a593Smuzhiyun }
144*4882a593Smuzhiyun
145*4882a593Smuzhiyun /* Extract useful items */
146*4882a593Smuzhiyun
147*4882a593Smuzhiyun obj_desc = *stack_ptr;
148*4882a593Smuzhiyun
149*4882a593Smuzhiyun /* Decode the descriptor type */
150*4882a593Smuzhiyun
151*4882a593Smuzhiyun switch (ACPI_GET_DESCRIPTOR_TYPE(obj_desc)) {
152*4882a593Smuzhiyun case ACPI_DESC_TYPE_NAMED:
153*4882a593Smuzhiyun
154*4882a593Smuzhiyun /* Namespace Node */
155*4882a593Smuzhiyun
156*4882a593Smuzhiyun object_type =
157*4882a593Smuzhiyun ((struct acpi_namespace_node *)obj_desc)->type;
158*4882a593Smuzhiyun
159*4882a593Smuzhiyun /*
160*4882a593Smuzhiyun * Resolve an alias object. The construction of these objects
161*4882a593Smuzhiyun * guarantees that there is only one level of alias indirection;
162*4882a593Smuzhiyun * thus, the attached object is always the aliased namespace node
163*4882a593Smuzhiyun */
164*4882a593Smuzhiyun if (object_type == ACPI_TYPE_LOCAL_ALIAS) {
165*4882a593Smuzhiyun obj_desc = acpi_ns_get_attached_object((struct
166*4882a593Smuzhiyun acpi_namespace_node
167*4882a593Smuzhiyun *)
168*4882a593Smuzhiyun obj_desc);
169*4882a593Smuzhiyun *stack_ptr = obj_desc;
170*4882a593Smuzhiyun object_type =
171*4882a593Smuzhiyun ((struct acpi_namespace_node *)obj_desc)->
172*4882a593Smuzhiyun type;
173*4882a593Smuzhiyun }
174*4882a593Smuzhiyun break;
175*4882a593Smuzhiyun
176*4882a593Smuzhiyun case ACPI_DESC_TYPE_OPERAND:
177*4882a593Smuzhiyun
178*4882a593Smuzhiyun /* ACPI internal object */
179*4882a593Smuzhiyun
180*4882a593Smuzhiyun object_type = obj_desc->common.type;
181*4882a593Smuzhiyun
182*4882a593Smuzhiyun /* Check for bad acpi_object_type */
183*4882a593Smuzhiyun
184*4882a593Smuzhiyun if (!acpi_ut_valid_object_type(object_type)) {
185*4882a593Smuzhiyun ACPI_ERROR((AE_INFO,
186*4882a593Smuzhiyun "Bad operand object type [0x%X]",
187*4882a593Smuzhiyun object_type));
188*4882a593Smuzhiyun
189*4882a593Smuzhiyun return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
190*4882a593Smuzhiyun }
191*4882a593Smuzhiyun
192*4882a593Smuzhiyun if (object_type == (u8) ACPI_TYPE_LOCAL_REFERENCE) {
193*4882a593Smuzhiyun
194*4882a593Smuzhiyun /* Validate the Reference */
195*4882a593Smuzhiyun
196*4882a593Smuzhiyun switch (obj_desc->reference.class) {
197*4882a593Smuzhiyun case ACPI_REFCLASS_DEBUG:
198*4882a593Smuzhiyun
199*4882a593Smuzhiyun target_op = AML_DEBUG_OP;
200*4882a593Smuzhiyun
201*4882a593Smuzhiyun /*lint -fallthrough */
202*4882a593Smuzhiyun
203*4882a593Smuzhiyun case ACPI_REFCLASS_ARG:
204*4882a593Smuzhiyun case ACPI_REFCLASS_LOCAL:
205*4882a593Smuzhiyun case ACPI_REFCLASS_INDEX:
206*4882a593Smuzhiyun case ACPI_REFCLASS_REFOF:
207*4882a593Smuzhiyun case ACPI_REFCLASS_TABLE: /* ddb_handle from LOAD_OP or LOAD_TABLE_OP */
208*4882a593Smuzhiyun case ACPI_REFCLASS_NAME: /* Reference to a named object */
209*4882a593Smuzhiyun
210*4882a593Smuzhiyun ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
211*4882a593Smuzhiyun "Operand is a Reference, Class [%s] %2.2X\n",
212*4882a593Smuzhiyun acpi_ut_get_reference_name
213*4882a593Smuzhiyun (obj_desc),
214*4882a593Smuzhiyun obj_desc->reference.
215*4882a593Smuzhiyun class));
216*4882a593Smuzhiyun break;
217*4882a593Smuzhiyun
218*4882a593Smuzhiyun default:
219*4882a593Smuzhiyun
220*4882a593Smuzhiyun ACPI_ERROR((AE_INFO,
221*4882a593Smuzhiyun "Unknown Reference Class 0x%2.2X in %p",
222*4882a593Smuzhiyun obj_desc->reference.class,
223*4882a593Smuzhiyun obj_desc));
224*4882a593Smuzhiyun
225*4882a593Smuzhiyun return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
226*4882a593Smuzhiyun }
227*4882a593Smuzhiyun }
228*4882a593Smuzhiyun break;
229*4882a593Smuzhiyun
230*4882a593Smuzhiyun default:
231*4882a593Smuzhiyun
232*4882a593Smuzhiyun /* Invalid descriptor */
233*4882a593Smuzhiyun
234*4882a593Smuzhiyun ACPI_ERROR((AE_INFO, "Invalid descriptor %p [%s]",
235*4882a593Smuzhiyun obj_desc,
236*4882a593Smuzhiyun acpi_ut_get_descriptor_name(obj_desc)));
237*4882a593Smuzhiyun
238*4882a593Smuzhiyun return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
239*4882a593Smuzhiyun }
240*4882a593Smuzhiyun
241*4882a593Smuzhiyun /* Get one argument type, point to the next */
242*4882a593Smuzhiyun
243*4882a593Smuzhiyun this_arg_type = GET_CURRENT_ARG_TYPE(arg_types);
244*4882a593Smuzhiyun INCREMENT_ARG_LIST(arg_types);
245*4882a593Smuzhiyun
246*4882a593Smuzhiyun /*
247*4882a593Smuzhiyun * Handle cases where the object does not need to be
248*4882a593Smuzhiyun * resolved to a value
249*4882a593Smuzhiyun */
250*4882a593Smuzhiyun switch (this_arg_type) {
251*4882a593Smuzhiyun case ARGI_REF_OR_STRING: /* Can be a String or Reference */
252*4882a593Smuzhiyun
253*4882a593Smuzhiyun if ((ACPI_GET_DESCRIPTOR_TYPE(obj_desc) ==
254*4882a593Smuzhiyun ACPI_DESC_TYPE_OPERAND) &&
255*4882a593Smuzhiyun (obj_desc->common.type == ACPI_TYPE_STRING)) {
256*4882a593Smuzhiyun /*
257*4882a593Smuzhiyun * String found - the string references a named object and
258*4882a593Smuzhiyun * must be resolved to a node
259*4882a593Smuzhiyun */
260*4882a593Smuzhiyun goto next_operand;
261*4882a593Smuzhiyun }
262*4882a593Smuzhiyun
263*4882a593Smuzhiyun /*
264*4882a593Smuzhiyun * Else not a string - fall through to the normal Reference
265*4882a593Smuzhiyun * case below
266*4882a593Smuzhiyun */
267*4882a593Smuzhiyun /*lint -fallthrough */
268*4882a593Smuzhiyun
269*4882a593Smuzhiyun case ARGI_REFERENCE: /* References: */
270*4882a593Smuzhiyun case ARGI_INTEGER_REF:
271*4882a593Smuzhiyun case ARGI_OBJECT_REF:
272*4882a593Smuzhiyun case ARGI_DEVICE_REF:
273*4882a593Smuzhiyun case ARGI_TARGETREF: /* Allows implicit conversion rules before store */
274*4882a593Smuzhiyun case ARGI_FIXED_TARGET: /* No implicit conversion before store to target */
275*4882a593Smuzhiyun case ARGI_SIMPLE_TARGET: /* Name, Local, or arg - no implicit conversion */
276*4882a593Smuzhiyun case ARGI_STORE_TARGET:
277*4882a593Smuzhiyun
278*4882a593Smuzhiyun /*
279*4882a593Smuzhiyun * Need an operand of type ACPI_TYPE_LOCAL_REFERENCE
280*4882a593Smuzhiyun * A Namespace Node is OK as-is
281*4882a593Smuzhiyun */
282*4882a593Smuzhiyun if (ACPI_GET_DESCRIPTOR_TYPE(obj_desc) ==
283*4882a593Smuzhiyun ACPI_DESC_TYPE_NAMED) {
284*4882a593Smuzhiyun goto next_operand;
285*4882a593Smuzhiyun }
286*4882a593Smuzhiyun
287*4882a593Smuzhiyun status =
288*4882a593Smuzhiyun acpi_ex_check_object_type(ACPI_TYPE_LOCAL_REFERENCE,
289*4882a593Smuzhiyun object_type, obj_desc);
290*4882a593Smuzhiyun if (ACPI_FAILURE(status)) {
291*4882a593Smuzhiyun return_ACPI_STATUS(status);
292*4882a593Smuzhiyun }
293*4882a593Smuzhiyun goto next_operand;
294*4882a593Smuzhiyun
295*4882a593Smuzhiyun case ARGI_DATAREFOBJ: /* Store operator only */
296*4882a593Smuzhiyun /*
297*4882a593Smuzhiyun * We don't want to resolve index_op reference objects during
298*4882a593Smuzhiyun * a store because this would be an implicit de_ref_of operation.
299*4882a593Smuzhiyun * Instead, we just want to store the reference object.
300*4882a593Smuzhiyun * -- All others must be resolved below.
301*4882a593Smuzhiyun */
302*4882a593Smuzhiyun if ((opcode == AML_STORE_OP) &&
303*4882a593Smuzhiyun ((*stack_ptr)->common.type ==
304*4882a593Smuzhiyun ACPI_TYPE_LOCAL_REFERENCE)
305*4882a593Smuzhiyun && ((*stack_ptr)->reference.class ==
306*4882a593Smuzhiyun ACPI_REFCLASS_INDEX)) {
307*4882a593Smuzhiyun goto next_operand;
308*4882a593Smuzhiyun }
309*4882a593Smuzhiyun break;
310*4882a593Smuzhiyun
311*4882a593Smuzhiyun default:
312*4882a593Smuzhiyun
313*4882a593Smuzhiyun /* All cases covered above */
314*4882a593Smuzhiyun
315*4882a593Smuzhiyun break;
316*4882a593Smuzhiyun }
317*4882a593Smuzhiyun
318*4882a593Smuzhiyun /*
319*4882a593Smuzhiyun * Resolve this object to a value
320*4882a593Smuzhiyun */
321*4882a593Smuzhiyun status = acpi_ex_resolve_to_value(stack_ptr, walk_state);
322*4882a593Smuzhiyun if (ACPI_FAILURE(status)) {
323*4882a593Smuzhiyun return_ACPI_STATUS(status);
324*4882a593Smuzhiyun }
325*4882a593Smuzhiyun
326*4882a593Smuzhiyun /* Get the resolved object */
327*4882a593Smuzhiyun
328*4882a593Smuzhiyun obj_desc = *stack_ptr;
329*4882a593Smuzhiyun
330*4882a593Smuzhiyun /*
331*4882a593Smuzhiyun * Check the resulting object (value) type
332*4882a593Smuzhiyun */
333*4882a593Smuzhiyun switch (this_arg_type) {
334*4882a593Smuzhiyun /*
335*4882a593Smuzhiyun * For the simple cases, only one type of resolved object
336*4882a593Smuzhiyun * is allowed
337*4882a593Smuzhiyun */
338*4882a593Smuzhiyun case ARGI_MUTEX:
339*4882a593Smuzhiyun
340*4882a593Smuzhiyun /* Need an operand of type ACPI_TYPE_MUTEX */
341*4882a593Smuzhiyun
342*4882a593Smuzhiyun type_needed = ACPI_TYPE_MUTEX;
343*4882a593Smuzhiyun break;
344*4882a593Smuzhiyun
345*4882a593Smuzhiyun case ARGI_EVENT:
346*4882a593Smuzhiyun
347*4882a593Smuzhiyun /* Need an operand of type ACPI_TYPE_EVENT */
348*4882a593Smuzhiyun
349*4882a593Smuzhiyun type_needed = ACPI_TYPE_EVENT;
350*4882a593Smuzhiyun break;
351*4882a593Smuzhiyun
352*4882a593Smuzhiyun case ARGI_PACKAGE: /* Package */
353*4882a593Smuzhiyun
354*4882a593Smuzhiyun /* Need an operand of type ACPI_TYPE_PACKAGE */
355*4882a593Smuzhiyun
356*4882a593Smuzhiyun type_needed = ACPI_TYPE_PACKAGE;
357*4882a593Smuzhiyun break;
358*4882a593Smuzhiyun
359*4882a593Smuzhiyun case ARGI_ANYTYPE:
360*4882a593Smuzhiyun
361*4882a593Smuzhiyun /* Any operand type will do */
362*4882a593Smuzhiyun
363*4882a593Smuzhiyun type_needed = ACPI_TYPE_ANY;
364*4882a593Smuzhiyun break;
365*4882a593Smuzhiyun
366*4882a593Smuzhiyun case ARGI_DDBHANDLE:
367*4882a593Smuzhiyun
368*4882a593Smuzhiyun /* Need an operand of type ACPI_TYPE_DDB_HANDLE */
369*4882a593Smuzhiyun
370*4882a593Smuzhiyun type_needed = ACPI_TYPE_LOCAL_REFERENCE;
371*4882a593Smuzhiyun break;
372*4882a593Smuzhiyun
373*4882a593Smuzhiyun /*
374*4882a593Smuzhiyun * The more complex cases allow multiple resolved object types
375*4882a593Smuzhiyun */
376*4882a593Smuzhiyun case ARGI_INTEGER:
377*4882a593Smuzhiyun
378*4882a593Smuzhiyun /*
379*4882a593Smuzhiyun * Need an operand of type ACPI_TYPE_INTEGER, but we can
380*4882a593Smuzhiyun * implicitly convert from a STRING or BUFFER.
381*4882a593Smuzhiyun *
382*4882a593Smuzhiyun * Known as "Implicit Source Operand Conversion"
383*4882a593Smuzhiyun */
384*4882a593Smuzhiyun status = acpi_ex_convert_to_integer(obj_desc, stack_ptr,
385*4882a593Smuzhiyun ACPI_IMPLICIT_CONVERSION);
386*4882a593Smuzhiyun if (ACPI_FAILURE(status)) {
387*4882a593Smuzhiyun if (status == AE_TYPE) {
388*4882a593Smuzhiyun ACPI_ERROR((AE_INFO,
389*4882a593Smuzhiyun "Needed [Integer/String/Buffer], found [%s] %p",
390*4882a593Smuzhiyun acpi_ut_get_object_type_name
391*4882a593Smuzhiyun (obj_desc), obj_desc));
392*4882a593Smuzhiyun
393*4882a593Smuzhiyun return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
394*4882a593Smuzhiyun }
395*4882a593Smuzhiyun
396*4882a593Smuzhiyun return_ACPI_STATUS(status);
397*4882a593Smuzhiyun }
398*4882a593Smuzhiyun
399*4882a593Smuzhiyun if (obj_desc != *stack_ptr) {
400*4882a593Smuzhiyun acpi_ut_remove_reference(obj_desc);
401*4882a593Smuzhiyun }
402*4882a593Smuzhiyun goto next_operand;
403*4882a593Smuzhiyun
404*4882a593Smuzhiyun case ARGI_BUFFER:
405*4882a593Smuzhiyun /*
406*4882a593Smuzhiyun * Need an operand of type ACPI_TYPE_BUFFER,
407*4882a593Smuzhiyun * But we can implicitly convert from a STRING or INTEGER
408*4882a593Smuzhiyun * aka - "Implicit Source Operand Conversion"
409*4882a593Smuzhiyun */
410*4882a593Smuzhiyun status = acpi_ex_convert_to_buffer(obj_desc, stack_ptr);
411*4882a593Smuzhiyun if (ACPI_FAILURE(status)) {
412*4882a593Smuzhiyun if (status == AE_TYPE) {
413*4882a593Smuzhiyun ACPI_ERROR((AE_INFO,
414*4882a593Smuzhiyun "Needed [Integer/String/Buffer], found [%s] %p",
415*4882a593Smuzhiyun acpi_ut_get_object_type_name
416*4882a593Smuzhiyun (obj_desc), obj_desc));
417*4882a593Smuzhiyun
418*4882a593Smuzhiyun return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
419*4882a593Smuzhiyun }
420*4882a593Smuzhiyun
421*4882a593Smuzhiyun return_ACPI_STATUS(status);
422*4882a593Smuzhiyun }
423*4882a593Smuzhiyun
424*4882a593Smuzhiyun if (obj_desc != *stack_ptr) {
425*4882a593Smuzhiyun acpi_ut_remove_reference(obj_desc);
426*4882a593Smuzhiyun }
427*4882a593Smuzhiyun goto next_operand;
428*4882a593Smuzhiyun
429*4882a593Smuzhiyun case ARGI_STRING:
430*4882a593Smuzhiyun /*
431*4882a593Smuzhiyun * Need an operand of type ACPI_TYPE_STRING,
432*4882a593Smuzhiyun * But we can implicitly convert from a BUFFER or INTEGER
433*4882a593Smuzhiyun * aka - "Implicit Source Operand Conversion"
434*4882a593Smuzhiyun */
435*4882a593Smuzhiyun status =
436*4882a593Smuzhiyun acpi_ex_convert_to_string(obj_desc, stack_ptr,
437*4882a593Smuzhiyun ACPI_IMPLICIT_CONVERT_HEX);
438*4882a593Smuzhiyun if (ACPI_FAILURE(status)) {
439*4882a593Smuzhiyun if (status == AE_TYPE) {
440*4882a593Smuzhiyun ACPI_ERROR((AE_INFO,
441*4882a593Smuzhiyun "Needed [Integer/String/Buffer], found [%s] %p",
442*4882a593Smuzhiyun acpi_ut_get_object_type_name
443*4882a593Smuzhiyun (obj_desc), obj_desc));
444*4882a593Smuzhiyun
445*4882a593Smuzhiyun return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
446*4882a593Smuzhiyun }
447*4882a593Smuzhiyun
448*4882a593Smuzhiyun return_ACPI_STATUS(status);
449*4882a593Smuzhiyun }
450*4882a593Smuzhiyun
451*4882a593Smuzhiyun if (obj_desc != *stack_ptr) {
452*4882a593Smuzhiyun acpi_ut_remove_reference(obj_desc);
453*4882a593Smuzhiyun }
454*4882a593Smuzhiyun goto next_operand;
455*4882a593Smuzhiyun
456*4882a593Smuzhiyun case ARGI_COMPUTEDATA:
457*4882a593Smuzhiyun
458*4882a593Smuzhiyun /* Need an operand of type INTEGER, STRING or BUFFER */
459*4882a593Smuzhiyun
460*4882a593Smuzhiyun switch (obj_desc->common.type) {
461*4882a593Smuzhiyun case ACPI_TYPE_INTEGER:
462*4882a593Smuzhiyun case ACPI_TYPE_STRING:
463*4882a593Smuzhiyun case ACPI_TYPE_BUFFER:
464*4882a593Smuzhiyun
465*4882a593Smuzhiyun /* Valid operand */
466*4882a593Smuzhiyun break;
467*4882a593Smuzhiyun
468*4882a593Smuzhiyun default:
469*4882a593Smuzhiyun ACPI_ERROR((AE_INFO,
470*4882a593Smuzhiyun "Needed [Integer/String/Buffer], found [%s] %p",
471*4882a593Smuzhiyun acpi_ut_get_object_type_name
472*4882a593Smuzhiyun (obj_desc), obj_desc));
473*4882a593Smuzhiyun
474*4882a593Smuzhiyun return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
475*4882a593Smuzhiyun }
476*4882a593Smuzhiyun goto next_operand;
477*4882a593Smuzhiyun
478*4882a593Smuzhiyun case ARGI_BUFFER_OR_STRING:
479*4882a593Smuzhiyun
480*4882a593Smuzhiyun /* Need an operand of type STRING or BUFFER */
481*4882a593Smuzhiyun
482*4882a593Smuzhiyun switch (obj_desc->common.type) {
483*4882a593Smuzhiyun case ACPI_TYPE_STRING:
484*4882a593Smuzhiyun case ACPI_TYPE_BUFFER:
485*4882a593Smuzhiyun
486*4882a593Smuzhiyun /* Valid operand */
487*4882a593Smuzhiyun break;
488*4882a593Smuzhiyun
489*4882a593Smuzhiyun case ACPI_TYPE_INTEGER:
490*4882a593Smuzhiyun
491*4882a593Smuzhiyun /* Highest priority conversion is to type Buffer */
492*4882a593Smuzhiyun
493*4882a593Smuzhiyun status =
494*4882a593Smuzhiyun acpi_ex_convert_to_buffer(obj_desc,
495*4882a593Smuzhiyun stack_ptr);
496*4882a593Smuzhiyun if (ACPI_FAILURE(status)) {
497*4882a593Smuzhiyun return_ACPI_STATUS(status);
498*4882a593Smuzhiyun }
499*4882a593Smuzhiyun
500*4882a593Smuzhiyun if (obj_desc != *stack_ptr) {
501*4882a593Smuzhiyun acpi_ut_remove_reference(obj_desc);
502*4882a593Smuzhiyun }
503*4882a593Smuzhiyun break;
504*4882a593Smuzhiyun
505*4882a593Smuzhiyun default:
506*4882a593Smuzhiyun ACPI_ERROR((AE_INFO,
507*4882a593Smuzhiyun "Needed [Integer/String/Buffer], found [%s] %p",
508*4882a593Smuzhiyun acpi_ut_get_object_type_name
509*4882a593Smuzhiyun (obj_desc), obj_desc));
510*4882a593Smuzhiyun
511*4882a593Smuzhiyun return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
512*4882a593Smuzhiyun }
513*4882a593Smuzhiyun goto next_operand;
514*4882a593Smuzhiyun
515*4882a593Smuzhiyun case ARGI_DATAOBJECT:
516*4882a593Smuzhiyun /*
517*4882a593Smuzhiyun * ARGI_DATAOBJECT is only used by the size_of operator.
518*4882a593Smuzhiyun * Need a buffer, string, package, or ref_of reference.
519*4882a593Smuzhiyun *
520*4882a593Smuzhiyun * The only reference allowed here is a direct reference to
521*4882a593Smuzhiyun * a namespace node.
522*4882a593Smuzhiyun */
523*4882a593Smuzhiyun switch (obj_desc->common.type) {
524*4882a593Smuzhiyun case ACPI_TYPE_PACKAGE:
525*4882a593Smuzhiyun case ACPI_TYPE_STRING:
526*4882a593Smuzhiyun case ACPI_TYPE_BUFFER:
527*4882a593Smuzhiyun case ACPI_TYPE_LOCAL_REFERENCE:
528*4882a593Smuzhiyun
529*4882a593Smuzhiyun /* Valid operand */
530*4882a593Smuzhiyun break;
531*4882a593Smuzhiyun
532*4882a593Smuzhiyun default:
533*4882a593Smuzhiyun
534*4882a593Smuzhiyun ACPI_ERROR((AE_INFO,
535*4882a593Smuzhiyun "Needed [Buffer/String/Package/Reference], found [%s] %p",
536*4882a593Smuzhiyun acpi_ut_get_object_type_name
537*4882a593Smuzhiyun (obj_desc), obj_desc));
538*4882a593Smuzhiyun
539*4882a593Smuzhiyun return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
540*4882a593Smuzhiyun }
541*4882a593Smuzhiyun goto next_operand;
542*4882a593Smuzhiyun
543*4882a593Smuzhiyun case ARGI_COMPLEXOBJ:
544*4882a593Smuzhiyun
545*4882a593Smuzhiyun /* Need a buffer or package or (ACPI 2.0) String */
546*4882a593Smuzhiyun
547*4882a593Smuzhiyun switch (obj_desc->common.type) {
548*4882a593Smuzhiyun case ACPI_TYPE_PACKAGE:
549*4882a593Smuzhiyun case ACPI_TYPE_STRING:
550*4882a593Smuzhiyun case ACPI_TYPE_BUFFER:
551*4882a593Smuzhiyun
552*4882a593Smuzhiyun /* Valid operand */
553*4882a593Smuzhiyun break;
554*4882a593Smuzhiyun
555*4882a593Smuzhiyun default:
556*4882a593Smuzhiyun
557*4882a593Smuzhiyun ACPI_ERROR((AE_INFO,
558*4882a593Smuzhiyun "Needed [Buffer/String/Package], found [%s] %p",
559*4882a593Smuzhiyun acpi_ut_get_object_type_name
560*4882a593Smuzhiyun (obj_desc), obj_desc));
561*4882a593Smuzhiyun
562*4882a593Smuzhiyun return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
563*4882a593Smuzhiyun }
564*4882a593Smuzhiyun goto next_operand;
565*4882a593Smuzhiyun
566*4882a593Smuzhiyun case ARGI_REGION_OR_BUFFER: /* Used by Load() only */
567*4882a593Smuzhiyun
568*4882a593Smuzhiyun /*
569*4882a593Smuzhiyun * Need an operand of type REGION or a BUFFER
570*4882a593Smuzhiyun * (which could be a resolved region field)
571*4882a593Smuzhiyun */
572*4882a593Smuzhiyun switch (obj_desc->common.type) {
573*4882a593Smuzhiyun case ACPI_TYPE_BUFFER:
574*4882a593Smuzhiyun case ACPI_TYPE_REGION:
575*4882a593Smuzhiyun
576*4882a593Smuzhiyun /* Valid operand */
577*4882a593Smuzhiyun break;
578*4882a593Smuzhiyun
579*4882a593Smuzhiyun default:
580*4882a593Smuzhiyun
581*4882a593Smuzhiyun ACPI_ERROR((AE_INFO,
582*4882a593Smuzhiyun "Needed [Region/Buffer], found [%s] %p",
583*4882a593Smuzhiyun acpi_ut_get_object_type_name
584*4882a593Smuzhiyun (obj_desc), obj_desc));
585*4882a593Smuzhiyun
586*4882a593Smuzhiyun return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
587*4882a593Smuzhiyun }
588*4882a593Smuzhiyun goto next_operand;
589*4882a593Smuzhiyun
590*4882a593Smuzhiyun case ARGI_DATAREFOBJ:
591*4882a593Smuzhiyun
592*4882a593Smuzhiyun /* Used by the Store() operator only */
593*4882a593Smuzhiyun
594*4882a593Smuzhiyun switch (obj_desc->common.type) {
595*4882a593Smuzhiyun case ACPI_TYPE_INTEGER:
596*4882a593Smuzhiyun case ACPI_TYPE_PACKAGE:
597*4882a593Smuzhiyun case ACPI_TYPE_STRING:
598*4882a593Smuzhiyun case ACPI_TYPE_BUFFER:
599*4882a593Smuzhiyun case ACPI_TYPE_BUFFER_FIELD:
600*4882a593Smuzhiyun case ACPI_TYPE_LOCAL_REFERENCE:
601*4882a593Smuzhiyun case ACPI_TYPE_LOCAL_REGION_FIELD:
602*4882a593Smuzhiyun case ACPI_TYPE_LOCAL_BANK_FIELD:
603*4882a593Smuzhiyun case ACPI_TYPE_LOCAL_INDEX_FIELD:
604*4882a593Smuzhiyun case ACPI_TYPE_DDB_HANDLE:
605*4882a593Smuzhiyun
606*4882a593Smuzhiyun /* Valid operand */
607*4882a593Smuzhiyun break;
608*4882a593Smuzhiyun
609*4882a593Smuzhiyun default:
610*4882a593Smuzhiyun
611*4882a593Smuzhiyun if (acpi_gbl_enable_interpreter_slack) {
612*4882a593Smuzhiyun /*
613*4882a593Smuzhiyun * Enable original behavior of Store(), allowing any
614*4882a593Smuzhiyun * and all objects as the source operand. The ACPI
615*4882a593Smuzhiyun * spec does not allow this, however.
616*4882a593Smuzhiyun */
617*4882a593Smuzhiyun break;
618*4882a593Smuzhiyun }
619*4882a593Smuzhiyun
620*4882a593Smuzhiyun if (target_op == AML_DEBUG_OP) {
621*4882a593Smuzhiyun
622*4882a593Smuzhiyun /* Allow store of any object to the Debug object */
623*4882a593Smuzhiyun
624*4882a593Smuzhiyun break;
625*4882a593Smuzhiyun }
626*4882a593Smuzhiyun
627*4882a593Smuzhiyun ACPI_ERROR((AE_INFO,
628*4882a593Smuzhiyun "Needed Integer/Buffer/String/Package/Ref/Ddb]"
629*4882a593Smuzhiyun ", found [%s] %p",
630*4882a593Smuzhiyun acpi_ut_get_object_type_name
631*4882a593Smuzhiyun (obj_desc), obj_desc));
632*4882a593Smuzhiyun
633*4882a593Smuzhiyun return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
634*4882a593Smuzhiyun }
635*4882a593Smuzhiyun goto next_operand;
636*4882a593Smuzhiyun
637*4882a593Smuzhiyun default:
638*4882a593Smuzhiyun
639*4882a593Smuzhiyun /* Unknown type */
640*4882a593Smuzhiyun
641*4882a593Smuzhiyun ACPI_ERROR((AE_INFO,
642*4882a593Smuzhiyun "Internal - Unknown ARGI (required operand) type 0x%X",
643*4882a593Smuzhiyun this_arg_type));
644*4882a593Smuzhiyun
645*4882a593Smuzhiyun return_ACPI_STATUS(AE_BAD_PARAMETER);
646*4882a593Smuzhiyun }
647*4882a593Smuzhiyun
648*4882a593Smuzhiyun /*
649*4882a593Smuzhiyun * Make sure that the original object was resolved to the
650*4882a593Smuzhiyun * required object type (Simple cases only).
651*4882a593Smuzhiyun */
652*4882a593Smuzhiyun status =
653*4882a593Smuzhiyun acpi_ex_check_object_type(type_needed,
654*4882a593Smuzhiyun (*stack_ptr)->common.type,
655*4882a593Smuzhiyun *stack_ptr);
656*4882a593Smuzhiyun if (ACPI_FAILURE(status)) {
657*4882a593Smuzhiyun return_ACPI_STATUS(status);
658*4882a593Smuzhiyun }
659*4882a593Smuzhiyun
660*4882a593Smuzhiyun next_operand:
661*4882a593Smuzhiyun /*
662*4882a593Smuzhiyun * If more operands needed, decrement stack_ptr to point
663*4882a593Smuzhiyun * to next operand on stack
664*4882a593Smuzhiyun */
665*4882a593Smuzhiyun if (GET_CURRENT_ARG_TYPE(arg_types)) {
666*4882a593Smuzhiyun stack_ptr--;
667*4882a593Smuzhiyun }
668*4882a593Smuzhiyun }
669*4882a593Smuzhiyun
670*4882a593Smuzhiyun ACPI_DUMP_OPERANDS(walk_state->operands,
671*4882a593Smuzhiyun acpi_ps_get_opcode_name(opcode),
672*4882a593Smuzhiyun walk_state->num_operands);
673*4882a593Smuzhiyun
674*4882a593Smuzhiyun return_ACPI_STATUS(status);
675*4882a593Smuzhiyun }
676