2 /******************************************************************************
4 * Module Name: amresop - AML Interpreter operand/object resolution
7 *****************************************************************************/
10 * Copyright (C) 2000, 2001 R. Byron Moore
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
38 #define _COMPONENT ACPI_EXECUTER
39 MODULE_NAME ("amresop")
42 /*******************************************************************************
44 * FUNCTION: Acpi_aml_check_object_type
46 * PARAMETERS: Type_needed Object type needed
47 * This_type Actual object type
48 * Object Object pointer
52 * DESCRIPTION: Check required type against actual type
54 ******************************************************************************/
57 acpi_aml_check_object_type (
58 ACPI_OBJECT_TYPE type_needed
,
59 ACPI_OBJECT_TYPE this_type
,
64 if (type_needed
== ACPI_TYPE_ANY
) {
65 /* All types OK, so we don't perform any typechecks */
71 if (type_needed
!= this_type
) {
72 return (AE_AML_OPERAND_TYPE
);
80 /*******************************************************************************
82 * FUNCTION: Acpi_aml_resolve_operands
84 * PARAMETERS: Opcode Opcode being interpreted
85 * Stack_ptr Top of operand stack
89 * DESCRIPTION: Convert stack entries to required types
91 * Each nibble in Arg_types represents one required operand
92 * and indicates the required Type:
94 * The corresponding stack entry will be converted to the
95 * required type if possible, else return an exception
97 ******************************************************************************/
100 acpi_aml_resolve_operands (
102 ACPI_OPERAND_OBJECT
**stack_ptr
,
103 ACPI_WALK_STATE
*walk_state
)
105 ACPI_OPERAND_OBJECT
*obj_desc
;
106 ACPI_STATUS status
= AE_OK
;
108 ACPI_HANDLE temp_handle
;
110 ACPI_OPCODE_INFO
*op_info
;
112 ACPI_OBJECT_TYPE type_needed
;
115 op_info
= acpi_ps_get_opcode_info (opcode
);
116 if (ACPI_GET_OP_TYPE (op_info
) != ACPI_OP_TYPE_OPCODE
) {
117 return (AE_AML_BAD_OPCODE
);
121 arg_types
= op_info
->runtime_args
;
122 if (arg_types
== ARGI_INVALID_OPCODE
) {
123 return (AE_AML_INTERNAL
);
128 * Normal exit is with *Types == '\0' at end of string.
129 * Function will return an exception from within the loop upon
130 * finding an entry which is not, and cannot be converted
131 * to, the required type; if stack underflows; or upon
132 * finding a NULL stack entry (which "should never happen").
135 while (GET_CURRENT_ARG_TYPE (arg_types
)) {
136 if (!stack_ptr
|| !*stack_ptr
) {
137 return (AE_AML_INTERNAL
);
140 /* Extract useful items */
142 obj_desc
= *stack_ptr
;
144 /* Decode the descriptor type */
146 if (VALID_DESCRIPTOR_TYPE (obj_desc
, ACPI_DESC_TYPE_NAMED
)) {
149 object_type
= ((ACPI_NAMESPACE_NODE
*) obj_desc
)->type
;
152 else if (VALID_DESCRIPTOR_TYPE (obj_desc
, ACPI_DESC_TYPE_INTERNAL
)) {
153 /* ACPI internal object */
155 object_type
= obj_desc
->common
.type
;
157 /* Check for bad ACPI_OBJECT_TYPE */
159 if (!acpi_aml_validate_object_type (object_type
)) {
160 return (AE_AML_OPERAND_TYPE
);
163 if (object_type
== (u8
) INTERNAL_TYPE_REFERENCE
) {
165 * Decode the Reference
168 op_info
= acpi_ps_get_opcode_info (opcode
);
169 if (ACPI_GET_OP_TYPE (op_info
) != ACPI_OP_TYPE_OPCODE
) {
170 return (AE_AML_BAD_OPCODE
);
174 switch (obj_desc
->reference
.opcode
) {
187 return (AE_AML_OPERAND_TYPE
);
194 /* Invalid descriptor */
196 return (AE_AML_OPERAND_TYPE
);
201 * Get one argument type, point to the next
204 this_arg_type
= GET_CURRENT_ARG_TYPE (arg_types
);
205 INCREMENT_ARG_LIST (arg_types
);
209 * Handle cases where the object does not need to be
210 * resolved to a value
213 switch (this_arg_type
) {
215 case ARGI_REFERENCE
: /* References */
216 case ARGI_INTEGER_REF
:
217 case ARGI_OBJECT_REF
:
218 case ARGI_DEVICE_REF
:
219 case ARGI_TARGETREF
: /* TBD: must implement implicit conversion rules before store */
220 case ARGI_FIXED_TARGET
: /* No implicit conversion before store to target */
221 case ARGI_SIMPLE_TARGET
: /* Name, Local, or Arg - no implicit conversion */
223 /* Need an operand of type INTERNAL_TYPE_REFERENCE */
225 if (VALID_DESCRIPTOR_TYPE (obj_desc
, ACPI_DESC_TYPE_NAMED
)) /* direct name ptr OK as-is */ {
229 status
= acpi_aml_check_object_type (INTERNAL_TYPE_REFERENCE
,
230 object_type
, obj_desc
);
231 if (ACPI_FAILURE (status
)) {
236 if (AML_NAME_OP
== obj_desc
->reference
.opcode
) {
238 * Convert an indirect name ptr to direct name ptr and put
242 temp_handle
= obj_desc
->reference
.object
;
243 acpi_cm_remove_reference (obj_desc
);
244 (*stack_ptr
) = temp_handle
;
254 * We don't want to resolve Index_op reference objects during
255 * a store because this would be an implicit De_ref_of operation.
256 * Instead, we just want to store the reference object.
257 * -- All others must be resolved below.
260 if ((opcode
== AML_STORE_OP
) &&
261 ((*stack_ptr
)->common
.type
== INTERNAL_TYPE_REFERENCE
) &&
262 ((*stack_ptr
)->reference
.opcode
== AML_INDEX_OP
)) {
270 * Resolve this object to a value
273 status
= acpi_aml_resolve_to_value (stack_ptr
, walk_state
);
274 if (ACPI_FAILURE (status
)) {
280 * Check the resulting object (value) type
282 switch (this_arg_type
) {
284 * For the simple cases, only one type of resolved object
289 /* Need an operand of type ACPI_TYPE_MUTEX */
291 type_needed
= ACPI_TYPE_MUTEX
;
296 /* Need an operand of type ACPI_TYPE_EVENT */
298 type_needed
= ACPI_TYPE_EVENT
;
303 /* Need an operand of type ACPI_TYPE_REGION */
305 type_needed
= ACPI_TYPE_REGION
;
308 case ARGI_IF
: /* If */
310 /* Need an operand of type INTERNAL_TYPE_IF */
312 type_needed
= INTERNAL_TYPE_IF
;
315 case ARGI_PACKAGE
: /* Package */
317 /* Need an operand of type ACPI_TYPE_PACKAGE */
319 type_needed
= ACPI_TYPE_PACKAGE
;
324 /* Any operand type will do */
326 type_needed
= ACPI_TYPE_ANY
;
331 * The more complex cases allow multiple resolved object types
334 case ARGI_INTEGER
: /* Number */
337 * Need an operand of type ACPI_TYPE_INTEGER,
338 * But we can implicitly convert from a STRING or BUFFER
340 status
= acpi_aml_convert_to_integer (stack_ptr
, walk_state
);
341 if (ACPI_FAILURE (status
)) {
342 if (status
== AE_TYPE
) {
343 return (AE_AML_OPERAND_TYPE
);
356 * Need an operand of type ACPI_TYPE_BUFFER,
357 * But we can implicitly convert from a STRING or INTEGER
359 status
= acpi_aml_convert_to_buffer (stack_ptr
, walk_state
);
360 if (ACPI_FAILURE (status
)) {
361 if (status
== AE_TYPE
) {
362 return (AE_AML_OPERAND_TYPE
);
375 * Need an operand of type ACPI_TYPE_STRING,
376 * But we can implicitly convert from a BUFFER or INTEGER
378 status
= acpi_aml_convert_to_string (stack_ptr
, walk_state
);
379 if (ACPI_FAILURE (status
)) {
380 if (status
== AE_TYPE
) {
381 return (AE_AML_OPERAND_TYPE
);
391 case ARGI_COMPUTEDATA
:
393 /* Need an operand of type INTEGER, STRING or BUFFER */
395 if ((ACPI_TYPE_INTEGER
!= (*stack_ptr
)->common
.type
) &&
396 (ACPI_TYPE_STRING
!= (*stack_ptr
)->common
.type
) &&
397 (ACPI_TYPE_BUFFER
!= (*stack_ptr
)->common
.type
)) {
398 return (AE_AML_OPERAND_TYPE
);
404 case ARGI_DATAOBJECT
:
406 * ARGI_DATAOBJECT is only used by the Size_of operator.
408 * The ACPI specification allows Size_of to return the size of
409 * a Buffer, String or Package. However, the MS ACPI.SYS AML
410 * Interpreter also allows an Node reference to return without
411 * error with a size of 4.
414 /* Need a buffer, string, package or Node reference */
416 if (((*stack_ptr
)->common
.type
!= ACPI_TYPE_BUFFER
) &&
417 ((*stack_ptr
)->common
.type
!= ACPI_TYPE_STRING
) &&
418 ((*stack_ptr
)->common
.type
!= ACPI_TYPE_PACKAGE
) &&
419 ((*stack_ptr
)->common
.type
!= INTERNAL_TYPE_REFERENCE
)) {
420 return (AE_AML_OPERAND_TYPE
);
424 * If this is a reference, only allow a reference to an Node.
426 if ((*stack_ptr
)->common
.type
== INTERNAL_TYPE_REFERENCE
) {
427 if (!(*stack_ptr
)->reference
.node
) {
428 return (AE_AML_OPERAND_TYPE
);
435 case ARGI_COMPLEXOBJ
:
437 /* Need a buffer or package */
439 if (((*stack_ptr
)->common
.type
!= ACPI_TYPE_BUFFER
) &&
440 ((*stack_ptr
)->common
.type
!= ACPI_TYPE_PACKAGE
)) {
441 return (AE_AML_OPERAND_TYPE
);
451 return (AE_BAD_PARAMETER
);
456 * Make sure that the original object was resolved to the
457 * required object type (Simple cases only).
459 status
= acpi_aml_check_object_type (type_needed
,
460 (*stack_ptr
)->common
.type
, *stack_ptr
);
461 if (ACPI_FAILURE (status
)) {
468 * If more operands needed, decrement Stack_ptr to point
469 * to next operand on stack
471 if (GET_CURRENT_ARG_TYPE (arg_types
)) {
475 } /* while (*Types) */