- Kai Germaschewski: ISDN update (including Makefiles)
[davej-history.git] / drivers / acpi / interpreter / amresop.c
blob83fda445505b5efd3f51fb690ac3868a595635ca
2 /******************************************************************************
4 * Module Name: amresop - AML Interpreter operand/object resolution
5 * $Revision: 18 $
7 *****************************************************************************/
9 /*
10 * Copyright (C) 2000 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
28 #include "acpi.h"
29 #include "amlcode.h"
30 #include "acparser.h"
31 #include "acdispat.h"
32 #include "acinterp.h"
33 #include "acnamesp.h"
34 #include "actables.h"
35 #include "acevents.h"
38 #define _COMPONENT INTERPRETER
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
50 * RETURN: Status
52 * DESCRIPTION: Check required type against actual type
54 ******************************************************************************/
56 ACPI_STATUS
57 acpi_aml_check_object_type (
58 ACPI_OBJECT_TYPE type_needed,
59 ACPI_OBJECT_TYPE this_type,
60 void *object)
64 if (type_needed == ACPI_TYPE_ANY) {
65 /* All types OK, so we don't perform any typechecks */
67 return (AE_OK);
71 if (type_needed != this_type) {
72 return (AE_AML_OPERAND_TYPE);
76 return (AE_OK);
80 /*******************************************************************************
82 * FUNCTION: Acpi_aml_resolve_operands
84 * PARAMETERS: Opcode Opcode being interpreted
85 * Stack_ptr Top of operand stack
87 * RETURN: Status
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 ******************************************************************************/
99 ACPI_STATUS
100 acpi_aml_resolve_operands (
101 u16 opcode,
102 ACPI_OPERAND_OBJECT **stack_ptr,
103 ACPI_WALK_STATE *walk_state)
105 ACPI_OPERAND_OBJECT *obj_desc;
106 ACPI_STATUS status = AE_OK;
107 u8 object_type;
108 ACPI_HANDLE temp_handle;
109 u32 arg_types;
110 ACPI_OPCODE_INFO *op_info;
111 u32 this_arg_type;
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)) {
147 /* Node */
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.op_code)
176 case AML_ZERO_OP:
177 case AML_ONE_OP:
178 case AML_ONES_OP:
179 case AML_DEBUG_OP:
180 case AML_NAME_OP:
181 case AML_INDEX_OP:
182 case AML_ARG_OP:
183 case AML_LOCAL_OP:
185 break;
187 default:
188 return (AE_AML_OPERAND_TYPE);
189 break;
194 else {
195 /* Invalid descriptor */
197 return (AE_AML_OPERAND_TYPE);
202 * Get one argument type, point to the next
205 this_arg_type = GET_CURRENT_ARG_TYPE (arg_types);
206 INCREMENT_ARG_LIST (arg_types);
210 * Handle cases where the object does not need to be
211 * resolved to a value
214 switch (this_arg_type)
217 case ARGI_REFERENCE: /* Reference */
218 case ARGI_TARGETREF:
220 /* Need an operand of type INTERNAL_TYPE_REFERENCE */
222 if (VALID_DESCRIPTOR_TYPE (obj_desc, ACPI_DESC_TYPE_NAMED)) /* direct name ptr OK as-is */ {
223 goto next_operand;
226 status = acpi_aml_check_object_type (INTERNAL_TYPE_REFERENCE,
227 object_type, obj_desc);
228 if (ACPI_FAILURE (status)) {
229 return (status);
233 if (AML_NAME_OP == obj_desc->reference.op_code) {
235 * Convert an indirect name ptr to direct name ptr and put
236 * it on the stack
239 temp_handle = obj_desc->reference.object;
240 acpi_cm_remove_reference (obj_desc);
241 (*stack_ptr) = temp_handle;
244 goto next_operand;
245 break;
248 case ARGI_ANYTYPE:
251 * We don't want to resolve Index_op reference objects during
252 * a store because this would be an implicit De_ref_of operation.
253 * Instead, we just want to store the reference object.
254 * -- All others must be resolved below.
257 if ((opcode == AML_STORE_OP) &&
258 ((*stack_ptr)->common.type == INTERNAL_TYPE_REFERENCE) &&
259 ((*stack_ptr)->reference.op_code == AML_INDEX_OP))
261 goto next_operand;
263 break;
268 * Resolve this object to a value
271 status = acpi_aml_resolve_to_value (stack_ptr, walk_state);
272 if (ACPI_FAILURE (status)) {
273 return (status);
278 * Check the resulting object (value) type
280 switch (this_arg_type)
283 * For the simple cases, only one type of resolved object
284 * is allowed
286 case ARGI_NUMBER: /* Number */
288 /* Need an operand of type ACPI_TYPE_NUMBER */
290 type_needed = ACPI_TYPE_NUMBER;
291 break;
293 case ARGI_BUFFER:
295 /* Need an operand of type ACPI_TYPE_BUFFER */
297 type_needed = ACPI_TYPE_BUFFER;
298 break;
300 case ARGI_MUTEX:
302 /* Need an operand of type ACPI_TYPE_MUTEX */
304 type_needed = ACPI_TYPE_MUTEX;
305 break;
307 case ARGI_EVENT:
309 /* Need an operand of type ACPI_TYPE_EVENT */
311 type_needed = ACPI_TYPE_EVENT;
312 break;
314 case ARGI_REGION:
316 /* Need an operand of type ACPI_TYPE_REGION */
318 type_needed = ACPI_TYPE_REGION;
319 break;
321 case ARGI_IF: /* If */
323 /* Need an operand of type INTERNAL_TYPE_IF */
325 type_needed = INTERNAL_TYPE_IF;
326 break;
328 case ARGI_PACKAGE: /* Package */
330 /* Need an operand of type ACPI_TYPE_PACKAGE */
332 type_needed = ACPI_TYPE_PACKAGE;
333 break;
335 case ARGI_ANYTYPE:
337 /* Any operand type will do */
339 type_needed = ACPI_TYPE_ANY;
340 break;
344 * The more complex cases allow multiple resolved object types
347 case ARGI_STRING:
349 /* Need an operand of type ACPI_TYPE_STRING or ACPI_TYPE_BUFFER */
351 if ((ACPI_TYPE_STRING != (*stack_ptr)->common.type) &&
352 (ACPI_TYPE_BUFFER != (*stack_ptr)->common.type))
354 return (AE_AML_OPERAND_TYPE);
356 goto next_operand;
357 break;
360 case ARGI_DATAOBJECT:
362 * ARGI_DATAOBJECT is only used by the Size_of operator.
364 * The ACPI specification allows Size_of to return the size of
365 * a Buffer, String or Package. However, the MS ACPI.SYS AML
366 * Interpreter also allows an Node reference to return without
367 * error with a size of 4.
370 /* Need a buffer, string, package or Node reference */
372 if (((*stack_ptr)->common.type != ACPI_TYPE_BUFFER) &&
373 ((*stack_ptr)->common.type != ACPI_TYPE_STRING) &&
374 ((*stack_ptr)->common.type != ACPI_TYPE_PACKAGE) &&
375 ((*stack_ptr)->common.type != INTERNAL_TYPE_REFERENCE))
377 return (AE_AML_OPERAND_TYPE);
381 * If this is a reference, only allow a reference to an Node.
383 if ((*stack_ptr)->common.type == INTERNAL_TYPE_REFERENCE) {
384 if (!(*stack_ptr)->reference.node) {
385 return (AE_AML_OPERAND_TYPE);
388 goto next_operand;
389 break;
392 case ARGI_COMPLEXOBJ:
394 /* Need a buffer or package */
396 if (((*stack_ptr)->common.type != ACPI_TYPE_BUFFER) &&
397 ((*stack_ptr)->common.type != ACPI_TYPE_PACKAGE))
399 return (AE_AML_OPERAND_TYPE);
401 goto next_operand;
402 break;
405 default:
407 /* Unknown type */
409 return (AE_BAD_PARAMETER);
414 * Make sure that the original object was resolved to the
415 * required object type (Simple cases only).
417 status = acpi_aml_check_object_type (type_needed,
418 (*stack_ptr)->common.type, *stack_ptr);
419 if (ACPI_FAILURE (status)) {
420 return (status);
424 next_operand:
426 * If more operands needed, decrement Stack_ptr to point
427 * to next operand on stack
429 if (GET_CURRENT_ARG_TYPE (arg_types)) {
430 stack_ptr--;
433 } /* while (*Types) */
436 return (status);